From 1109132f09d75da9a28b649c7677bb6ce07c40c0 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:41:45 -0500 Subject: initial commit --- .../accessibility_troubleshooting/index.html | 144 ++ .../accessibility/css_and_javascript/index.html | 359 ++++ files/es/learn/accessibility/html/index.html | 588 ++++++ files/es/learn/accessibility/index.html | 60 + files/es/learn/accessibility/mobile/index.html | 346 ++++ .../qu\303\251_es_la_accesibilidad/index.html" | 211 +++ files/es/learn/aprender_y_obtener_ayuda/index.html | 321 ++++ files/es/learn/codificacion-scripting/index.html | 10 + .../common_questions/cuanto_cuesta/index.html | 162 ++ .../dise\303\261os_web_comunes/index.html" | 115 ++ .../how_does_the_internet_work/index.html | 99 + files/es/learn/common_questions/index.html | 145 ++ .../index.html | 119 ++ .../que_es_un_servidor_web/index.html | 120 ++ .../que_software_necesito/index.html | 226 +++ .../qu\303\251_es_una_url/index.html" | 152 ++ .../set_up_a_local_testing_server/index.html | 113 ++ .../thinking_before_coding/index.html | 177 ++ .../what_are_browser_developer_tools/index.html | 248 +++ .../what_are_hyperlinks/index.html | 91 + .../what_is_a_domain_name/index.html | 157 ++ files/es/learn/como_contribuir/index.html | 88 + .../building_blocks/cascada_y_herencia/index.html | 333 ++++ .../contenido_desbordado/index.html | 123 ++ .../css/building_blocks/depurar_el_css/index.html | 198 ++ .../dimensionar_elementos_en_css/index.html | 129 ++ .../building_blocks/el_modelo_de_caja/index.html | 343 ++++ .../css/building_blocks/fondos_y_bordes/index.html | 306 +++ .../index.html" | 193 ++ files/es/learn/css/building_blocks/index.html | 94 + .../index.html | 165 ++ .../selectores_css/combinadores/index.html | 111 ++ .../css/building_blocks/selectores_css/index.html | 223 +++ .../pseudo-clases_y_pseudo-elementos/index.html | 397 ++++ .../selectores_de_atributos/index.html | 154 ++ .../selectores_de_tipo_clase_e_id/index.html | 117 ++ .../css/building_blocks/styling_tables/index.html | 282 +++ .../valores_y_unidades_css/index.html | 392 ++++ .../css_layout/dise\303\261o_receptivo/index.html" | 324 ++++ files/es/learn/css/css_layout/flexbox/index.html | 337 ++++ files/es/learn/css/css_layout/floats/index.html | 505 +++++ .../learn/css/css_layout/flujo_normal/index.html | 95 + files/es/learn/css/css_layout/grids/index.html | 696 +++++++ files/es/learn/css/css_layout/index.html | 87 + .../css/css_layout/introducci\303\263n/index.html" | 701 +++++++ .../es/learn/css/css_layout/positioning/index.html | 469 +++++ .../soporte_a_navegadores_antiguos/index.html | 237 +++ .../css/first_steps/comenzando_css/index.html | 264 +++ .../css/first_steps/como_funciona_css/index.html | 156 ++ .../first_steps/como_se_estructura_css/index.html | 512 +++++ files/es/learn/css/first_steps/index.html | 52 + .../css/first_steps/qu\303\251_es_css/index.html" | 127 ++ .../usa_tu_nuevo_conocimiento/index.html | 100 + files/es/learn/css/index.html | 63 + .../fundamental_css_comprehension/index.html | 117 ++ .../learn/css/styling_text/fuentes_web/index.html | 197 ++ .../learn/css/styling_text/fundamentals/index.html | 732 +++++++ files/es/learn/css/styling_text/index.html | 57 + .../css/styling_text/styling_links/index.html | 434 +++++ .../css/styling_text/styling_lists/index.html | 392 ++++ .../s\303\241bercomo/generated_content/index.html" | 178 ++ "files/es/learn/css/s\303\241bercomo/index.html" | 81 + files/es/learn/desarrollo_web_front-end/index.html | 201 ++ .../css_basics/index.html | 283 +++ .../c\303\263mo_funciona_la_web/index.html" | 100 + .../html_basics/index.html | 224 +++ .../learn/getting_started_with_the_web/index.html | 68 + .../instalacion_de_software_basico/index.html | 83 + .../javascript_basics/index.html | 456 +++++ .../la_web_y_los_estandares_web/index.html | 172 ++ .../manejando_los_archivos/index.html | 120 ++ .../publishing_your_website/index.html | 195 ++ .../what_will_your_website_look_like/index.html | 113 ++ .../cross_browser_testing/index.html | 39 + .../learn/herramientas_y_pruebas/github/index.html | 92 + files/es/learn/herramientas_y_pruebas/index.html | 58 + .../index.html | 133 ++ .../react_getting_started/index.html | 476 +++++ .../vue_primeros_pasos/index.html | 294 +++ .../understanding_client-side_tools/index.html | 46 + files/es/learn/html/como/index.html | 141 ++ .../html/como/usando_atributos_de_datos/index.html | 75 + .../index.html | 786 ++++++++ .../forms/how_to_structure_an_html_form/index.html | 320 ++++ files/es/learn/html/forms/index.html | 366 ++++ .../index.html | 2003 ++++++++++++++++++++ .../index.html | 75 + .../index.html | 87 + .../sending_and_retrieving_form_data/index.html | 328 ++++ .../learn/html/forms/styling_html_forms/index.html | 345 ++++ .../html/forms/the_native_form_widgets/index.html | 326 ++++ .../learn/html/forms/tipos_input_html5/index.html | 276 +++ .../forms/validacion_formulario_datos/index.html | 845 +++++++++ .../html/forms/your_first_html_form/index.html | 305 +++ files/es/learn/html/index.html | 66 + .../advanced_text_formatting/index.html | 695 +++++++ .../creating_hyperlinks/index.html | 346 ++++ .../introduccion_a_html/debugging_html/index.html | 171 ++ .../html/introduccion_a_html/estructura/index.html | 298 +++ .../index.html" | 105 + files/es/learn/html/introduccion_a_html/index.html | 77 + .../html/introduccion_a_html/iniciar/index.html | 767 ++++++++ .../marking_up_a_letter/index.html | 88 + .../html/introduccion_a_html/metados_en/index.html | 299 +++ .../index.html | 99 + .../index.html" | 72 + .../index.html | 67 + .../html/introduccion_a_html/texto/index.html | 970 ++++++++++ .../adding_vector_graphics_to_the_web/index.html | 366 ++++ .../images_in_html/index.html | 510 +++++ .../learn/html/multimedia_and_embedding/index.html | 73 + .../mozilla_splash_page/index.html | 138 ++ .../other_embedding_technologies/index.html | 371 ++++ .../responsive_images/index.html | 265 +++ .../video_and_audio_content/index.html | 319 ++++ .../index.html" | 563 ++++++ .../index.html | 471 +++++ files/es/learn/html/tablas/index.html | 34 + .../html/tablas/structuring_planet_data/index.html | 72 + files/es/learn/index.html | 135 ++ .../javascript/asynchronous/async_await/index.html | 411 ++++ .../javascript/asynchronous/concepts/index.html | 162 ++ files/es/learn/javascript/asynchronous/index.html | 43 + .../building_blocks/bucle_codigo/index.html | 923 +++++++++ .../building_blocks/conditionals/index.html | 778 ++++++++ .../construyendo_tu_propia_funcion/index.html | 252 +++ .../javascript/building_blocks/eventos/index.html | 578 ++++++ .../building_blocks/functions/index.html | 400 ++++ .../building_blocks/galeria_de_imagenes/index.html | 144 ++ .../es/learn/javascript/building_blocks/index.html | 71 + .../building_blocks/return_values/index.html | 168 ++ .../client-side_storage/index.html | 788 ++++++++ .../client-side_web_apis/fetching_data/index.html | 373 ++++ .../javascript/client-side_web_apis/index.html | 53 + .../introducci\303\263n/index.html" | 274 +++ .../first_steps/a_first_splash/index.html | 613 ++++++ .../learn/javascript/first_steps/arrays/index.html | 665 +++++++ .../generador_de_historias_absurdas/index.html | 147 ++ files/es/learn/javascript/first_steps/index.html | 88 + .../first_steps/matem\303\241ticas/index.html" | 443 +++++ .../index.html | 122 ++ .../qu\303\251_es_javascript/index.html" | 436 +++++ .../javascript/first_steps/strings/index.html | 299 +++ .../test_your_skills_colon__math/index.html | 91 + .../test_your_skills_colon__variables/index.html | 84 + .../first_steps/useful_string_methods/index.html | 718 +++++++ .../javascript/first_steps/variables/index.html | 340 ++++ .../first_steps/what_went_wrong/index.html | 268 +++ files/es/learn/javascript/howto/index.html | 317 ++++ files/es/learn/javascript/index.html | 80 + .../adding_bouncing_balls_features/index.html | 205 ++ .../es/learn/javascript/objects/basics/index.html | 259 +++ .../index.html" | 301 +++ files/es/learn/javascript/objects/index.html | 67 + .../javascript/objects/inheritance/index.html | 400 ++++ files/es/learn/javascript/objects/json/index.html | 339 ++++ .../objects/object-oriented_js/index.html | 307 +++ .../objects/object_prototypes/index.html | 282 +++ files/es/learn/performance/index.html | 113 ++ .../learn/server-side/django/admin_site/index.html | 372 ++++ .../server-side/django/authentication/index.html | 714 +++++++ .../learn/server-side/django/deployment/index.html | 672 +++++++ .../django/development_environment/index.html | 421 ++++ .../django/django_assessment_blog/index.html | 307 +++ files/es/learn/server-side/django/forms/index.html | 661 +++++++ .../server-side/django/generic_views/index.html | 640 +++++++ .../learn/server-side/django/home_page/index.html | 403 ++++ files/es/learn/server-side/django/index.html | 66 + .../django/introducci\303\263n/index.html" | 282 +++ .../es/learn/server-side/django/models/index.html | 490 +++++ .../learn/server-side/django/sessions/index.html | 200 ++ .../server-side/django/skeleton_website/index.html | 397 ++++ .../es/learn/server-side/django/testing/index.html | 906 +++++++++ .../tutorial_local_library_website/index.html | 103 + .../django/web_application_security/index.html | 176 ++ .../development_environment/index.html | 407 ++++ .../es/learn/server-side/express_nodejs/index.html | 76 + .../express_nodejs/introduction/index.html | 498 +++++ .../server-side/express_nodejs/mongoose/index.html | 801 ++++++++ .../express_nodejs/skeleton_website/index.html | 502 +++++ .../tutorial_local_library_website/index.html | 83 + files/es/learn/server-side/index.html | 57 + .../node_server_without_framework/index.html | 81 + .../es/learn/server-side/primeros_pasos/index.html | 47 + .../primeros_pasos/introducci\303\263n/index.html" | 192 ++ .../primeros_pasos/seguridad_sitios_web/index.html | 177 ++ .../vision_general_cliente_servidor/index.html | 334 ++++ .../primeros_pasos/web_frameworks/index.html | 306 +++ files/es/learn/using_github_pages/index.html | 103 + 189 files changed, 54268 insertions(+) create mode 100644 files/es/learn/accessibility/accessibility_troubleshooting/index.html create mode 100644 files/es/learn/accessibility/css_and_javascript/index.html create mode 100644 files/es/learn/accessibility/html/index.html create mode 100644 files/es/learn/accessibility/index.html create mode 100644 files/es/learn/accessibility/mobile/index.html create mode 100644 "files/es/learn/accessibility/qu\303\251_es_la_accesibilidad/index.html" create mode 100644 files/es/learn/aprender_y_obtener_ayuda/index.html create mode 100644 files/es/learn/codificacion-scripting/index.html create mode 100644 files/es/learn/common_questions/cuanto_cuesta/index.html create mode 100644 "files/es/learn/common_questions/dise\303\261os_web_comunes/index.html" create mode 100644 files/es/learn/common_questions/how_does_the_internet_work/index.html create mode 100644 files/es/learn/common_questions/index.html create mode 100644 files/es/learn/common_questions/pages_sites_servers_and_search_engines/index.html create mode 100644 files/es/learn/common_questions/que_es_un_servidor_web/index.html create mode 100644 files/es/learn/common_questions/que_software_necesito/index.html create mode 100644 "files/es/learn/common_questions/qu\303\251_es_una_url/index.html" create mode 100644 files/es/learn/common_questions/set_up_a_local_testing_server/index.html create mode 100644 files/es/learn/common_questions/thinking_before_coding/index.html create mode 100644 files/es/learn/common_questions/what_are_browser_developer_tools/index.html create mode 100644 files/es/learn/common_questions/what_are_hyperlinks/index.html create mode 100644 files/es/learn/common_questions/what_is_a_domain_name/index.html create mode 100644 files/es/learn/como_contribuir/index.html create mode 100644 files/es/learn/css/building_blocks/cascada_y_herencia/index.html create mode 100644 files/es/learn/css/building_blocks/contenido_desbordado/index.html create mode 100644 files/es/learn/css/building_blocks/depurar_el_css/index.html create mode 100644 files/es/learn/css/building_blocks/dimensionar_elementos_en_css/index.html create mode 100644 files/es/learn/css/building_blocks/el_modelo_de_caja/index.html create mode 100644 files/es/learn/css/building_blocks/fondos_y_bordes/index.html create mode 100644 "files/es/learn/css/building_blocks/im\303\241genes_medios_y_elementos_de_formulario/index.html" create mode 100644 files/es/learn/css/building_blocks/index.html create mode 100644 files/es/learn/css/building_blocks/manejando_diferentes_direcciones_de_texto/index.html create mode 100644 files/es/learn/css/building_blocks/selectores_css/combinadores/index.html create mode 100644 files/es/learn/css/building_blocks/selectores_css/index.html create mode 100644 files/es/learn/css/building_blocks/selectores_css/pseudo-clases_y_pseudo-elementos/index.html create mode 100644 files/es/learn/css/building_blocks/selectores_css/selectores_de_atributos/index.html create mode 100644 files/es/learn/css/building_blocks/selectores_css/selectores_de_tipo_clase_e_id/index.html create mode 100644 files/es/learn/css/building_blocks/styling_tables/index.html create mode 100644 files/es/learn/css/building_blocks/valores_y_unidades_css/index.html create mode 100644 "files/es/learn/css/css_layout/dise\303\261o_receptivo/index.html" create mode 100644 files/es/learn/css/css_layout/flexbox/index.html create mode 100644 files/es/learn/css/css_layout/floats/index.html create mode 100644 files/es/learn/css/css_layout/flujo_normal/index.html create mode 100644 files/es/learn/css/css_layout/grids/index.html create mode 100644 files/es/learn/css/css_layout/index.html create mode 100644 "files/es/learn/css/css_layout/introducci\303\263n/index.html" create mode 100644 files/es/learn/css/css_layout/positioning/index.html create mode 100644 files/es/learn/css/css_layout/soporte_a_navegadores_antiguos/index.html create mode 100644 files/es/learn/css/first_steps/comenzando_css/index.html create mode 100644 files/es/learn/css/first_steps/como_funciona_css/index.html create mode 100644 files/es/learn/css/first_steps/como_se_estructura_css/index.html create mode 100644 files/es/learn/css/first_steps/index.html create mode 100644 "files/es/learn/css/first_steps/qu\303\251_es_css/index.html" create mode 100644 files/es/learn/css/first_steps/usa_tu_nuevo_conocimiento/index.html create mode 100644 files/es/learn/css/index.html create mode 100644 files/es/learn/css/introduction_to_css/fundamental_css_comprehension/index.html create mode 100644 files/es/learn/css/styling_text/fuentes_web/index.html create mode 100644 files/es/learn/css/styling_text/fundamentals/index.html create mode 100644 files/es/learn/css/styling_text/index.html create mode 100644 files/es/learn/css/styling_text/styling_links/index.html create mode 100644 files/es/learn/css/styling_text/styling_lists/index.html create mode 100644 "files/es/learn/css/s\303\241bercomo/generated_content/index.html" create mode 100644 "files/es/learn/css/s\303\241bercomo/index.html" create mode 100644 files/es/learn/desarrollo_web_front-end/index.html create mode 100644 files/es/learn/getting_started_with_the_web/css_basics/index.html create mode 100644 "files/es/learn/getting_started_with_the_web/c\303\263mo_funciona_la_web/index.html" create mode 100644 files/es/learn/getting_started_with_the_web/html_basics/index.html create mode 100644 files/es/learn/getting_started_with_the_web/index.html create mode 100644 files/es/learn/getting_started_with_the_web/instalacion_de_software_basico/index.html create mode 100644 files/es/learn/getting_started_with_the_web/javascript_basics/index.html create mode 100644 files/es/learn/getting_started_with_the_web/la_web_y_los_estandares_web/index.html create mode 100644 files/es/learn/getting_started_with_the_web/manejando_los_archivos/index.html create mode 100644 files/es/learn/getting_started_with_the_web/publishing_your_website/index.html create mode 100644 files/es/learn/getting_started_with_the_web/what_will_your_website_look_like/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/cross_browser_testing/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/github/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/react_getting_started/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/vue_primeros_pasos/index.html create mode 100644 files/es/learn/herramientas_y_pruebas/understanding_client-side_tools/index.html create mode 100644 files/es/learn/html/como/index.html create mode 100644 files/es/learn/html/como/usando_atributos_de_datos/index.html create mode 100644 files/es/learn/html/forms/como_crear_widgets_de_formularios_personalizados/index.html create mode 100644 files/es/learn/html/forms/how_to_structure_an_html_form/index.html create mode 100644 files/es/learn/html/forms/index.html create mode 100644 files/es/learn/html/forms/property_compatibility_table_for_form_controls/index.html create mode 100644 files/es/learn/html/forms/prueba_tus_habilidades_colon__controles_html5/index.html create mode 100644 files/es/learn/html/forms/prueba_tus_habilidades_colon__otros_controles/index.html create mode 100644 files/es/learn/html/forms/sending_and_retrieving_form_data/index.html create mode 100644 files/es/learn/html/forms/styling_html_forms/index.html create mode 100644 files/es/learn/html/forms/the_native_form_widgets/index.html create mode 100644 files/es/learn/html/forms/tipos_input_html5/index.html create mode 100644 files/es/learn/html/forms/validacion_formulario_datos/index.html create mode 100644 files/es/learn/html/forms/your_first_html_form/index.html create mode 100644 files/es/learn/html/index.html create mode 100644 files/es/learn/html/introduccion_a_html/advanced_text_formatting/index.html create mode 100644 files/es/learn/html/introduccion_a_html/creating_hyperlinks/index.html create mode 100644 files/es/learn/html/introduccion_a_html/debugging_html/index.html create mode 100644 files/es/learn/html/introduccion_a_html/estructura/index.html create mode 100644 "files/es/learn/html/introduccion_a_html/estructuraci\303\263n_de_una_p\303\241gina_de_contenido/index.html" create mode 100644 files/es/learn/html/introduccion_a_html/index.html create mode 100644 files/es/learn/html/introduccion_a_html/iniciar/index.html create mode 100644 files/es/learn/html/introduccion_a_html/marking_up_a_letter/index.html create mode 100644 files/es/learn/html/introduccion_a_html/metados_en/index.html create mode 100644 files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__enlaces/index.html create mode 100644 "files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__texto_b\303\241sico_html/index.html" create mode 100644 files/es/learn/html/introduccion_a_html/test_your_skills_colon__advanced_html_text/index.html create mode 100644 files/es/learn/html/introduccion_a_html/texto/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/images_in_html/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/responsive_images/index.html create mode 100644 files/es/learn/html/multimedia_and_embedding/video_and_audio_content/index.html create mode 100644 "files/es/learn/html/tablas/conceptos_b\303\241sicos_de_las_tablas_html/index.html" create mode 100644 files/es/learn/html/tablas/funciones_avanzadas_de_las_tablas_html_y_accesibilidad/index.html create mode 100644 files/es/learn/html/tablas/index.html create mode 100644 files/es/learn/html/tablas/structuring_planet_data/index.html create mode 100644 files/es/learn/index.html create mode 100644 files/es/learn/javascript/asynchronous/async_await/index.html create mode 100644 files/es/learn/javascript/asynchronous/concepts/index.html create mode 100644 files/es/learn/javascript/asynchronous/index.html create mode 100644 files/es/learn/javascript/building_blocks/bucle_codigo/index.html create mode 100644 files/es/learn/javascript/building_blocks/conditionals/index.html create mode 100644 files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html create mode 100644 files/es/learn/javascript/building_blocks/eventos/index.html create mode 100644 files/es/learn/javascript/building_blocks/functions/index.html create mode 100644 files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html create mode 100644 files/es/learn/javascript/building_blocks/index.html create mode 100644 files/es/learn/javascript/building_blocks/return_values/index.html create mode 100644 files/es/learn/javascript/client-side_web_apis/client-side_storage/index.html create mode 100644 files/es/learn/javascript/client-side_web_apis/fetching_data/index.html create mode 100644 files/es/learn/javascript/client-side_web_apis/index.html create mode 100644 "files/es/learn/javascript/client-side_web_apis/introducci\303\263n/index.html" create mode 100644 files/es/learn/javascript/first_steps/a_first_splash/index.html create mode 100644 files/es/learn/javascript/first_steps/arrays/index.html create mode 100644 files/es/learn/javascript/first_steps/generador_de_historias_absurdas/index.html create mode 100644 files/es/learn/javascript/first_steps/index.html create mode 100644 "files/es/learn/javascript/first_steps/matem\303\241ticas/index.html" create mode 100644 files/es/learn/javascript/first_steps/prueba_tus_habilidades_colon__strings/index.html create mode 100644 "files/es/learn/javascript/first_steps/qu\303\251_es_javascript/index.html" create mode 100644 files/es/learn/javascript/first_steps/strings/index.html create mode 100644 files/es/learn/javascript/first_steps/test_your_skills_colon__math/index.html create mode 100644 files/es/learn/javascript/first_steps/test_your_skills_colon__variables/index.html create mode 100644 files/es/learn/javascript/first_steps/useful_string_methods/index.html create mode 100644 files/es/learn/javascript/first_steps/variables/index.html create mode 100644 files/es/learn/javascript/first_steps/what_went_wrong/index.html create mode 100644 files/es/learn/javascript/howto/index.html create mode 100644 files/es/learn/javascript/index.html create mode 100644 files/es/learn/javascript/objects/adding_bouncing_balls_features/index.html create mode 100644 files/es/learn/javascript/objects/basics/index.html create mode 100644 "files/es/learn/javascript/objects/ejercicio_pr\303\241ctico_de_construcci\303\263n_de_objetos/index.html" create mode 100644 files/es/learn/javascript/objects/index.html create mode 100644 files/es/learn/javascript/objects/inheritance/index.html create mode 100644 files/es/learn/javascript/objects/json/index.html create mode 100644 files/es/learn/javascript/objects/object-oriented_js/index.html create mode 100644 files/es/learn/javascript/objects/object_prototypes/index.html create mode 100644 files/es/learn/performance/index.html create mode 100644 files/es/learn/server-side/django/admin_site/index.html create mode 100644 files/es/learn/server-side/django/authentication/index.html create mode 100644 files/es/learn/server-side/django/deployment/index.html create mode 100644 files/es/learn/server-side/django/development_environment/index.html create mode 100644 files/es/learn/server-side/django/django_assessment_blog/index.html create mode 100644 files/es/learn/server-side/django/forms/index.html create mode 100644 files/es/learn/server-side/django/generic_views/index.html create mode 100644 files/es/learn/server-side/django/home_page/index.html create mode 100644 files/es/learn/server-side/django/index.html create mode 100644 "files/es/learn/server-side/django/introducci\303\263n/index.html" create mode 100644 files/es/learn/server-side/django/models/index.html create mode 100644 files/es/learn/server-side/django/sessions/index.html create mode 100644 files/es/learn/server-side/django/skeleton_website/index.html create mode 100644 files/es/learn/server-side/django/testing/index.html create mode 100644 files/es/learn/server-side/django/tutorial_local_library_website/index.html create mode 100644 files/es/learn/server-side/django/web_application_security/index.html create mode 100644 files/es/learn/server-side/express_nodejs/development_environment/index.html create mode 100644 files/es/learn/server-side/express_nodejs/index.html create mode 100644 files/es/learn/server-side/express_nodejs/introduction/index.html create mode 100644 files/es/learn/server-side/express_nodejs/mongoose/index.html create mode 100644 files/es/learn/server-side/express_nodejs/skeleton_website/index.html create mode 100644 files/es/learn/server-side/express_nodejs/tutorial_local_library_website/index.html create mode 100644 files/es/learn/server-side/index.html create mode 100644 files/es/learn/server-side/node_server_without_framework/index.html create mode 100644 files/es/learn/server-side/primeros_pasos/index.html create mode 100644 "files/es/learn/server-side/primeros_pasos/introducci\303\263n/index.html" create mode 100644 files/es/learn/server-side/primeros_pasos/seguridad_sitios_web/index.html create mode 100644 files/es/learn/server-side/primeros_pasos/vision_general_cliente_servidor/index.html create mode 100644 files/es/learn/server-side/primeros_pasos/web_frameworks/index.html create mode 100644 files/es/learn/using_github_pages/index.html (limited to 'files/es/learn') diff --git a/files/es/learn/accessibility/accessibility_troubleshooting/index.html b/files/es/learn/accessibility/accessibility_troubleshooting/index.html new file mode 100644 index 0000000000..2509ef8aa5 --- /dev/null +++ b/files/es/learn/accessibility/accessibility_troubleshooting/index.html @@ -0,0 +1,144 @@ +--- +title: 'Evaluación: Solución de problemas de accesibilidad' +slug: Learn/Accessibility/Accessibility_troubleshooting +tags: + - Accesibilidad + - Aprender + - CSS + - Evaluación + - HTML + - JavaScript + - Principiante + - WAI-ARIA +translation_of: Learn/Accessibility/Accessibility_troubleshooting +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}
+ +

En la evaluación de este módulo, le presentamos un sitio simple con una serie de problemas de accesibilidad que necesita diagnosticar y corregir.

+ + + + + + + + + + + + +
Requisitos previos:Conocimiento de informática básica, una comprensión básica de HTML, CSS y JavaScript, una comprensión de los artículos anteriores del curso.
Objectivo:Probar los conocimientos básicos de los fundamentos de accesibilidad.
+ +

Punto de partida

+ +

Para iniciar esta evaluación, debe ir y tomar el archivo ZIP que contiene los archivos que componen el ejemplo. Descomprima el contenido en un nuevo directorio en algún lugar del equipo local.

+ +

Alternativamente, podría usar un sitio como JSBin  o  Glitch  para hacer su evaluación. Puede pegar el HTML, CSS y JavaScript en uno de estos editores en línea. Si el editor en línea que está utilizando no tiene un panel CSS/JS independiente, no dude en colocarlos en elementos apropiados <style>  /  <script>.  

+ +

El sitio de evaluación terminado debe tener este aspecto:

+ +

+ +

Verá algunas diferencias/problemas con la visualización del estado inicial de la evaluación — esto se debe principalmente a las diferencias en el marcado, que a su vez causan algunos problemas de estilo, ya que el CSS no se aplica correctamente. No se preocupe, ¡estará solucionando estos problemas en las próximas secciones!

+ +
+ + + + + + +
+

Nota: Si se queda atorado, pídanos ayuda — consulta la sección Evaluación o más ayuda en la parte inferior de esta página.

+
+
+ +

Resumen del proyecto

+ +

Para este proyecto, se le presenta un sitio ficticio de la naturaleza que muestra un artículo "fáctico" sobre los osos. Tal como está, tiene una serie de problemas de accesibilidad: su tarea es explorar el sitio existente y solucionarlos lo mejor de sus capacidades, respondiendo a las preguntas que se indican a continuación.

+ +

Color

+ +

El texto es difícil de leer debido al esquema de color actual. ¿Puede realizar una prueba del contraste de color actual (texto/fondo), notificar los resultados de la prueba y, a continuación, corregirla cambiando los colores asignados?

+ +

HTML Semántico

+ +
    +
  1. El contenido todavía no es muy accesible: informe sobre lo que sucede cuando intenta navegar por él mediante un lector de pantalla.
  2. +
  3. ¿Puede actualizar el texto del artículo para facilitar la navegación de los usuarios del lector de pantalla?
  4. +
  5. La parte del menú de navegación del sitio (limitada por <div class="nav"></div>) podría ser más accesible poniéndolo en un elemento semántico HTML5 adecuado. ¿A cuál debería actualizarse? Realice la actualización.
  6. +
+ +
+ + + + + + +
+

Nota: Tendrá que actualizar los selectores de reglas CSS que estilan las etiquetas a sus equivalentes adecuados para los encabezados semánticos. Una vez que agregue elementos de párrafo, notará que el estilo se ve mejor.

+
+
+ +

Las imágenes

+ +

Las imágenes son actualmente inaccesibles para los usuarios del lector de pantalla. ¿Puede arreglarlo?

+ +

El reproductor de audio

+ +
    +
  1. El reproductor de <audio> no es accesible para personas con discapacidad auditiva (sordos) - ¿podría añadir algún tipo de alternativa accesible para estos usuarios?
  2. +
  3. El reproductor de <audio> no es accesible para aquellos que utilizan navegadores más antiguos que no admiten audio HTML5. ¿Cómo podrías permitir que sigan accediendo al audio?
  4. +
+ +

Los formularios

+ +
    +
  1. El elemento <input> en el formulario de búsqueda en la parte superior se podría hacer con una etiqueta, pero no queremos agregar una etiqueta de texto visible que potencialmente estropearía el diseño y realmente no es necesaria para los usuarios sin discapacidad visual. ¿Cómo podría agregar una etiqueta a la que solo puedan acceder los lectores de pantalla?
  2. +
  3. Los dos elementos <input> del formulario en el comentario tienen etiquetas de texto visibles, pero no están inequívocamente asociados con sus etiquetas, ¿cómo lograría esto? Tenga en cuenta que también tendrá que actualizar parte de la regla CSS.
  4. +
+ +

El control de mostrar/ocultar comentarios

+ +

El botón de control de mostrar/ocultar comentarios no es accesible por teclado actualmente. ¿Puede hacerlo accesible al teclado, tanto en términos de enfocarlo usando la tecla de tabulación como de activarlo usando la tecla de retorno?

+ +

La tabla

+ +

La tabla de datos no es muy accesible actualmente: es difícil para los usuarios del lector de pantalla asociar filas y columnas de datos, y la tabla tampoco tiene ningún tipo de resumen para dejar claro lo que muestra. ¿Puede agregar algunas características a su HTML para solucionar este problema?

+ +

¿Otras consideraciones?

+ +

¿Puede enumerar dos ideas más para mejoras que podrían hacer que el sitio web sea más accesible?

+ +

Evaluación o más ayuda

+ +

Si desea que se evalúe su trabajo, o si está atorado y desea pedir ayuda:

+ +
    +
  1. Ponga su trabajo en un editor compartible en línea como CodePen,  jsFiddleo  Glitch.
  2. +
  3. Escribe una publicación pidiendo evaluación y/o ayuda en la categoría Aprendizaje del foro de discurso mdn. Su publicación debe incluir:Un título descriptivo como "Evaluación deseada para la solución de problemas de accesibilidad".
  4. +
  5. +
      +
    • Detalles de lo que ya ha intentado, y lo que le gustaría que hagamos, por ejemplo, si está atascado y necesita ayuda, o quiere una evaluación.
    • +
    • Un enlace al ejemplo con el que desea evaluar o necesita ayuda, en un editor de compartición en línea (como se mencionó en el paso 1 anterior). Esta es una buena práctica a adquirir - es muy difícil ayudar a alguien con un problema de codificación si no se puede ver su código.
    • +
    • Un enlace a la tarea actual o página de evaluación, para que podamos encontrar la pregunta con la que desea ayuda.
    • +
    +
  6. +
+ +

{{PreviousMenu("Learn/Accessibility/Mobile", "Learn/Accessibility")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/accessibility/css_and_javascript/index.html b/files/es/learn/accessibility/css_and_javascript/index.html new file mode 100644 index 0000000000..5f12f39466 --- /dev/null +++ b/files/es/learn/accessibility/css_and_javascript/index.html @@ -0,0 +1,359 @@ +--- +title: Buenas prácticas de accesibilidad CSS y JavaScript +slug: Learn/Accessibility/CSS_and_JavaScript +translation_of: Learn/Accessibility/CSS_and_JavaScript +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
+ +

CSS y JavaScript, cuando se usan correctamente, también tienen el potencial de permitir experiencias web accesibles... o pueden dañar significativamente la accesibilidad si se usan incorrectamente. Este artículo describe algunas de las mejores prácticas de CSS y JavaScript que deben tenerse en cuenta para garantizar que incluso el contenido complejo sea lo más accesible posible.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conocimientos básicos de HTML, CSS y JavaScript, y comprensión de qué es la accesibilidad.
Objetivo: +

Familiarizarse con el uso apropiado de CSS y JavaScript en documentos web para maximizar la accesibilidad y no restarle valor.

+
+ +

¿CSS y JavaScript son accesibles?

+ +

CSS y JavaScript no tienen la misma importancia inmediata para la accesibilidad que HTML, pero aún así pueden ayudar o dañar la accesibilidad, dependiendo de cómo se usen. Para decirlo de otra manera, es importante considerar algunos consejos de buenas prácticas para asegurarse de que el uso de CSS y JavaScript no arruina la accesibilidad de tus documentos.

+ +

CSS

+ +

Comencemos estudiando CSS.

+ +

Semántica correcta y expectativas del usuario

+ +

Es posible usar CSS para hacer que cualquier elemento HTML se vea como cualquier cosa, pero esto no significa que deba hacerse. Como mencionamos con frecuencia en nuestro artículo HTML: Una buena base para la accesibilidad, debes usar el elemento semántico apropiado para cada cosa, siempre que sea posible. Si no lo haces, puede causar confusión y problemas de usabilidad para todos, pero especialmente para los usuarios con discapacidades. El uso de la semántica correcta tiene mucho que ver con las expectativas del usuario: los elementos se ven y se comportan de cierta manera, de acuerdo con su funcionalidad, y los usuarios esperan estas convenciones comunes.

+ +

Por ejemplo, un usuario de lector de pantalla no puede navegar por una página a través de elementos de encabezado si el desarrollador no ha utilizado adecuadamente los elementos de encabezado para marcar el contenido. Del mismo modo, un encabezado pierde su propósito visual si se le aplica un estilo para que no parezca un encabezado.

+ +

La regla general es que puede actualizar el estilo de una característica de la página para que se ajuste a tu diseño, pero no cambiarlo tanto como para que ya no se vea ni se comporte como se esperaba. Las siguientes secciones resumen las principales características de HTML a considerar.

+ +

Estructura de contenido de texto "estándar"

+ +

Encabezados, párrafos, listas: el contenido de texto central de su página:

+ +
<h1>Cabecera</h1>
+
+<p>Párrafo</p>
+
+<ul>
+  <li>Mi lista</li>
+  <li>tiene dos ítems.</li>
+</ul>
+ +

Un CSS típico podría tener este aspecto:

+ +
h1 {
+  font-size: 5rem;
+}
+
+p, li {
+  line-height: 1.5;
+  font-size: 1.6rem;
+}
+ +

Deberías:

+ + + +

Consulte Fundamentos del texto HTML y Estilo de texto para obtener más información.

+ +

Texto enfatizado

+ +

Marcado en línea que confiere un énfasis específico al texto que rodea:

+ +
<p>El agua está <em>muy caliente</em>.</p>
+
+<p>Las gotas de agua que se acumulan en las superficies se denominan <strong>condensación</strong>.</p>
+ +

Es posible que desees agregar algunos colores simples a su texto enfatizado:

+ +
strong, em {
+  color: #a60000;
+}
+ +

Sin embargo, rara vez necesitarás dar estilo a elementos de énfasis de manera significativa. Las convenciones estándar de texto en negrita y cursiva son muy reconocibles y cambiar el estilo puede causar confusión. Para obtener más información sobre el énfasis, consulte Énfasis e importancia.

+ +

Abreviaciones

+ +

Un elemento que permite asociar una abreviatura, un acrónimo o una inicialización a su expansión:

+ +
<p>El contenido web se marca usando <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
+ +

Nuevamente, es posible que desees darle estilo de una manera simple:

+ +
abbr {
+  color: #a60000;
+}
+ +

La convención de estilo reconocida para las abreviaturas es un subrayado punteado, y no es aconsejable desviarse significativamente de esto. Para obtener más información sobre abreviaturas, consulte Abreviaturas.

+ +

Enlaces

+ +

Hipervínculos: la forma de llegar a nuevos lugares en la web:

+ +
<p>Visita la <a href="https://www.mozilla.org">página de inicio de Mozilla</a>.</p>
+ +

A continuación se muestra un estilo de enlace muy simple:

+ +
a {
+  color: #ff0000;
+}
+
+a:hover, a:visited, a:focus {
+  color: #a60000;
+  text-decoration: none;
+}
+
+a:active {
+  color: #000000;
+  background-color: #a60000;
+}
+ +

Las convenciones de enlace estándar son subrayado y un color diferente (predeterminado: azul) en su estado estándar, otra variación de color cuando el enlace ha sido visitado anteriormente (predeterminado: púrpura) y otro color más cuando el enlace está activado (predeterminado: rojo) . Además, el puntero del ratón cambia a un ícono de puntero cuando se pasa el ratón sobre los enlaces, y el enlace recibe un resaltado cuando se enfoca (por ejemplo, mediante tabulación) o se activa. La siguiente imagen muestra el resaltado tanto en Firefox (contorno punteado) como en Chrome (contorno azul):

+ +

+ +

+ +

Puedes ser creativo con los estilos de enlaces, siempre y cuando sigas dando información a los usuarios cuando interactúan con los enlaces. Definitivamente, algo debería suceder cuando los estados cambian, y no debes deshacerte del cursor del puntero o del contorno; ambos son ayudas de accesibilidad muy importantes para quienes usan los controles del teclado.

+ +

Elementos de formulario

+ +

Elementos que permiten a los usuarios introducir datos en sitios web:

+ +
<div>
+  <label for="nombre">Entra tu nombre</label>
+  <input type="text" id="nombre" name="nombre">
+</div>
+ +

Puedes ver algunos buenos ejemplos de CSS en nuestro ejemplo de form-css.html (pruébalo en vivo también).

+ +

La mayor parte del CSS que escribirás para los formularios será para dimensionar los elementos, alinear las etiquetas y las entradas y hacer que se vean limpios y ordenados.

+ +

Sin embargo, no debes desviarse demasiado de la retroalimentación visual esperada que reciben los elementos del formulario cuando están enfocados, que es básicamente la mismo que con los enlaces (ver más arriba). Puedes aplicar estilos a los estados de enfoque / desplazamiento del formulario para que este comportamiento sea más coherente en todos los navegadores o se adapte mejor al diseño de tu página, pero no te deshagas de él por completo; de nuevo, las personas confían en estas pistas para ayudarles a saber qué está pasando.

+ +

Tablas

+ +

Tablas para presentar datos tabulares.

+ +

Puedes ver un buen y simple ejemplo de tabla HTML y CSS en nuestro ejemplo table-css.html (pruébalo en vivo también).

+ +

El CSS de tablas generalmente sirve para hacer que la tabla se adapte mejor a su diseño y se vea menos fea. Es una buena idea asegurarse de que los encabezados de la tabla se destaquen (normalmente en negrita) y usar rayas de cebra para que las diferentes filas sean más fáciles de analizar.

+ +

Color y contraste de color

+ +

Al elegir un esquema de color para tu sitio web, asegúrate de que el color del texto (primer plano) contrasta bien con el color de fondo. Tu diseño puede verse bien, pero no es bueno si las personas con discapacidades visuales como daltonismo no pueden leer tu contenido.

+ +

Existe una manera fácil de verificar si el contraste es lo suficientemente grande como para no causar problemas. Hay una serie de herramientas de verificación de contraste en línea en las que puede introduci los colores de primer plano y de fondo para verificarlos. Por ejemplo, el Comprobador de contraste de color de WebAIM es fácil de usar y proporciona una explicación de lo que necesitas para cumplir con los criterios WCAG sobre el contraste de color.

+ +
+

Nota: una relación de contraste alta también permitirá que cualquier persona que utilice un teléfono inteligente o una tableta con una pantalla brillante lea mejor las páginas cuando se encuentre en un entorno brillante, como a la luz del sol.

+
+ +

Otro consejo es no confiar solo en el color para las señales / información, ya que esto no será bueno para aquellos que no pueden ver el color. En lugar de marcar los campos de formulario obligatorios en rojo, por ejemplo, márcalos con un asterisco y en rojo.

+ +

Esconder cosas

+ +

Hay muchos casos en los que un diseño visual requerirá que no se muestre todo el contenido a la vez. Por ejemplo, en nuestro ejemplo de cuadro de información con pestañas (ver código fuente) tenemos tres paneles de información, pero los colocamos uno encima del otro y proporcionamos pestañas en las que se puede hacer clic para mostrar cada uno (también es accesible desde el teclado - pues usar alternativamente Tab y Enter / Return para seleccionarlos).

+ +

+ +

A los usuarios de lectores de pantalla no les importa nada de esto: están contentos con el contenido siempre que el orden del código fuente tenga sentido y puedan acceder a todo. El posicionamiento absoluto (como se usa en este ejemplo) generalmente se considera uno de los mejores mecanismos para ocultar contenido para lograr un efecto visual, porque no impide que los lectores de pantalla accedan a él.

+ +

Por otro lado, no debes usar {{cssxref ("visibility")}}: hidden o {{cssxref ("display")}}: none, porque ocultan el contenido de los lectores de pantalla. A menos que, por supuesto, exista una buena razón por la que desees ocultar este contenido a los lectores de pantalla.

+ +
+

Nota: Invisible Content Just for Screen Reader Users tiene muchos más detalles útiles sobre este tema.

+
+ +

Acepta que los usuarios pueden saltarse tus estilos

+ +

Es posible que los usuarios anulen tus estilos con sus propios estilos personalizados, por ejemplo:

+ + + +

Los usuarios pueden hacerlo por diversas razones. Un usuario con discapacidad visual puede querer agrandar el texto en todos los sitios web que visita, o un usuario con una deficiencia de color severa puede querer poner todos los sitios web en colores de alto contraste que sean fáciles de ver. Cualquiera que sea la necesidad, debes sentirse cómodo con esto y hacer que tus diseños sean lo suficientemente flexibles para que dichos cambios funcionen en tu diseño. Como ejemplo, es posible que desees asegurarte de que tu área de contenido principal pueda manejar texto más grande (tal vez comience a desplazarse para permitir que se vea todo), y no solo lo ocultará o romperá por completo.

+ +

JavaScript

+ +

JavaScript también puede romper la accesibilidad, dependiendo de cómo se use.

+ +

El JavaScript moderno es un lenguaje poderoso, y podemos hacer mucho con él actualmente, desde contenido simple y actualizaciones de la interfaz de usuario hasta juegos 2D y 3D completos. No existe una regla que diga que todo el contenido debe ser 100% accesible para todas las personas; solo debe hacer lo que pueda y hacer que sus aplicaciones sean lo más accesibles posible.

+ +

Se puede decir que el contenido y la funcionalidad simples son fáciles de hacer accesibles; por ejemplo, texto, imágenes, tablas, formularios y botones que activan funciones. Como vimos en nuestro artículo HTML: Una buena base para la accesibilidad, las consideraciones clave son:

+ + + +

También vimos un ejemplo de cómo usar JavaScript para incorporar la funcionalidad donde faltaba; consulta Volver a añadir la accesibilidad del teclado. Esto no es ideal; en realidad, deberías usar el elemento correcto para el trabajo correcto, pero demuestra que es posible en situaciones en las que, por alguna razón, no puedes controlar el marcado que se utiliza. Otra forma de mejorar la accesibilidad de los widgets no semánticos que funcionan con JavaScript es utilizar WAI-ARIA para proporcionar semántica adicional para los usuarios de lectores de pantalla. El próximo artículo también cubrirá esto en detalle.

+ +

Las funcionalidades complejas como los juegos en 3D no son tan fáciles de hacer accesibles: un juego en 3D complejo creado con WebGL se renderizará en un elemento {{htmlelement ("canvas")}}, que en este momento no tiene la capacidad de proporcionar alternativas de texto u otros información que pueden utilizar los usuarios con discapacidad visual grave. Se puede argumentar que un juego de este tipo no tiene realmente a este grupo de personas como parte de su público objetivo principal, y no sería razonable esperar que lo hicieras 100% accesible para las personas ciegas; sin embargo, podrías implementar controles de teclado para que sea utilizable por usuarios que no utilizan el ratóny hacer que el esquema de color sea lo suficientemente contrastante como para que lo puedan usar aquellos con deficiencias de color.

+ +

El problema de demasiado JavaScript

+ +

El problema a menudo surge cuando la gente confía demasiado en JavaScript. A veces verás un sitio web donde todo se ha hecho con JavaScript: el HTML ha sido generado por JavaScript, el CSS ha sido generado por JavaScript, etc. Esto tiene todo tipo de problemas de accesibilidad y otros asociados, por lo que no es aconsejado.

+ +

Además de utilizar el elemento correcto para el trabajo correcto, ¡también debes asegurarte de utilizar la tecnología adecuada para el trabajo correcto! Piensa detenidamente si necesitas ese brillante cuadro de información en 3D con JavaScript o si bastaría con texto antiguo sin formato. Piensa detenidamente si necesitas un widget de formulario no estándar complejo o si una entrada de texto sería suficiente. Y no generes todo tu contenido HTML usando JavaScript si es posible.

+ +

Hacerlo no intrusivo

+ +

Deberías hacer tu JavaScript no intrusivo al crear tu contenido. La idea de JavaScript no intrusivo es que debe usarse siempre que sea posible para mejorar la funcionalidad, no para construirlo todo; las funciones básicas deberían funcionar idealmente sin JavaScript, aunque sabemos que esto no siempre es una opción. Pero, de nuevo, una gran parte es usar las funcionalidades integradas del navegador siempre que sea posible.

+ +

Entre los buenos ejemplos de usos de JavaScript no intrusivo se incluyen:

+ + + +

Como ejemplo, hemos escrito un ejemplo rápido y sucio de validación de formulario del lado del cliente: consulta form-validation.html (y también la demostración en vivo). Aquí verás un formulario simple; al intentar enviar el formulario con uno o ambos campos vacíos, el envío falla y aparece un cuadro de mensaje de error para indicar cuál es el problema.
+
+ Este tipo de validación de formulario es no intrusiva: se puede usar el formulario perfectamente aunque JavaScript no esté disponible, y cualquier implementación de formulario razonable también tendrá activa la validación del lado del servidor, porque es demasiado fácil para los usuarios malintencionados eludir la validación del lado del cliente (por ejemplo, desactivando JavaScript en el navegador). La validación del lado del cliente sigue siendo realmente útil para informar de errores: los usuarios pueden saber los errores que cometen al instante, en lugar de tener que esperar un viaje de ida y vuelta al servidor y la recarga de la página. Esta es una clara ventaja de usabilidad.

+ +
+

Nota: la validación del lado del servidor no se ha implementado en esta simple demostración.

+
+ +

También hemos hecho que esta validación de formulario sea bastante accesible. Hemos utilizado elementos {{htmlelement ("label")}} para asegurarnos de que las etiquetas del formulario estén vinculadas de forma inequívoca a sus entradas, de modo que los lectores de pantalla puedan leerlas junto con ellas:

+ +
<label for="name">Entra tu nombre:</label>
+<input type="text" name="name" id="name">
+ +

Solo realizamos la validación cuando se envía el formulario; esto es para no actualizar la IU con demasiada frecuencia y confundir potencialmente a los lectores de pantalla (y posiblemente a otros) usuarios:

+ +
form.onsubmit = validate;
+
+function validate(e) {
+  errorList.innerHTML = '';
+  for(let i = 0; i < formItems.length; i++) {
+    const testItem = formItems[i];
+    if(testItem.input.value === '') {
+      errorField.style.left = '360px';
+      createLink(testItem);
+    }
+  }
+
+  if(errorList.innerHTML !== '') {
+    e.preventDefault();
+  }
+}
+ +
+

Nota: En este ejemplo estamos ocultando y mostrando el cuadro de mensaje de error utilizando posicionamiento absoluto en lugar de otro método como la visibilidad o la visualización, porque no interfiere con que el lector de pantalla pueda leer su contenido.

+
+ +

La validación real del formulario sería mucho más compleja que esto: querría verificar que el nombre entrado realmente parezca un nombre, la edad entrada sea realmente un número y sea realista (por ejemplo, no negativa y menor de 4 dígitos). Aquí acabamos de implementar una verificación simple de que se haya completado un valor en cada campo de entrada (if(testItem.input.value === '')).

+ +

Cuando se ha realizado la validación, si las pruebas pasan, se envía el formulario. Si hay errores (if (errorList.innerHTML! == '')), detenemos el envío del formulario (usando preventDefault()) y mostramos los mensajes de error que se hayan creado (ver más abajo). Este mecanismo significa que los errores solo se mostrarán si hay errores, lo que es mejor para la usabilidad.

+ +

Para cada entrada sin un valor completado cuando se envía el formulario, creamos un elemento de lista con un enlace y lo insertamos en errorList.

+ +
function createLink(testItem) {
+  const listItem = document.createElement('li');
+  const anchor = document.createElement('a');
+
+  anchor.textContent = 'El campo ' + testItem.input.name + ' está vacío. Entra tu ' + testItem.input.name + '.';
+  anchor.href = '#' + testItem.input.name;
+  anchor.onclick = function() {
+    testItem.input.focus();
+  };
+  listItem.appendChild(anchor);
+  errorList.appendChild(listItem);
+}
+ +

Cada enlace tiene un doble propósito: te dice cuál es el error, y además puedes hacer clic en él / activarlo para ir directamente al elemento de entrada en cuestión y corregir la entrada.

+ +
+

Nota: La parte focus() de este ejemplo es un poco complicada. Chrome y Edge darán foco al elemento al hacer clic en el enlace, sin necesidad del bloque onclick / focus(). Safari solo resaltará el elemento de formulario con el enlace por sí solo, por lo que necesita el bloque onclick / focus() para darle foco. Firefox no da foco a las entradas correctamente en este contexto, por lo que los usuarios de Firefox no pueden aprovechar esto en este momento (aunque todo lo demás funciona bien). El problema de Firefox debería solucionarse pronto; se está trabajando para que el comportamiento de Firefox sea igual al de otros navegadores (consulte {{bug (277178)}}).

+
+ +

Además, el errorField se coloca en la parte superior del orden de código (aunque se coloca de manera diferente en la interfaz de usuario usando CSS), lo que significa que los usuarios pueden averiguar exactamente qué está mal con los envíos de sus formularios y acceder a los elementos de entrada en cuestión retrocediendo hasta el inicio de la página.

+ +

Como nota final, hemos utilizado algunos atributos WAI-ARIA en nuestra demostración para ayudar a resolver los problemas de accesibilidad causados ​​por áreas de contenido que se actualizan constantemente sin recargar la página (los lectores de pantalla no captan esto ni alertan a los usuarios de forma predeterminada):

+ +
<div class="errors" role="alert" aria-relevant="all">
+  <ul>
+  </ul>
+</div>
+ +

Explicaremos estos atributos en nuestro próximo artículo, que cubre WAI-ARIA con mucho más detalle.

+ +
+

Nota: Algunos de vosotros probablemente estaréis pensando en el hecho de que los formularios HTML5 tienen mecanismos de validación integrados como los atributos required, min / minlength y max / maxlength (consultad la referencia del elemento {{htmlelement("input")}} para más información). No los hemos usado en la demostración porque la compatibilidad entre navegadores es irregular (por ejemplo, solo funciona en IE10 y versiones superiores).

+
+ +
+

Nota: Usable and Accessible Form Validation and Error Recovery, de WebAIM, proporciona más información útil sobre la validación de formularios accesibles.

+
+ +

Otros potenciales problemas de accesibilidad de JavaScript

+ +

Hay otras cosas que debes tener en cuenta al implementar JavaScript y pensar en la accesibilidad. Agregaremos más a medida que los encontremos.

+ +

Eventos específicos del ratón

+ +

Como sabrás, la mayoría de las interacciones de los usuarios se implementan en JavaScript del lado del cliente mediante controladores de eventos, que nos permiten ejecutar funciones en respuesta a ciertos eventos que suceden. Algunos eventos pueden tener problemas de accesibilidad. El ejemplo principal con el que se encontrará son los eventos específicos del ratón, como mouseover, mouseout, dblclick, etc. La funcionalidad que se ejecuta en respuesta a estos eventos no será accesible mediante otros mecanismos, como los controles del teclado.

+ +

Para mitigar estos problemas, debes duplicar estos eventos con eventos similares que se pueden activar por otros medios (los llamados controladores de eventos independientes de dispositivo); focus y blur proporcionarían accesibilidad para los usuarios del teclado.

+ +

Veamos un ejemplo que destaca cuándo esto podría ser útil. Tal vez queramos proporcionar una imagen en miniatura que muestre una versión más grande de la imagen cuando al colocar el ratón sobre ella o darle foco (como pasaría en un catálogo de productos de comercio electrónico).

+ +

Hemos creado un ejemplo muy simple, que puedes encontrar en mouse-and-keyboard-events.html (consulta también el código fuente). El código presenta dos funciones que muestran y ocultan la imagen ampliada; estas se ejecutan mediante las siguientes líneas que las configuran como controladores de eventos:

+ +
imgThumb.onmouseover = showImg;
+imgThumb.onmouseout = hideImg;
+
+imgThumb.onfocus = showImg;
+imgThumb.onblur = hideImg;
+ +

Las dos primeras líneas ejecutan las funciones cuando el puntero del ratón se desplaza sobre la miniatura y deja de hacerlo, respectivamente. Sin embargo, esto no nos permite acceder a la vista ampliada con el teclado; para hacerlo hemos incluido las dos últimas líneas, que ejecutan las funciones cuando la imagen toma y pierde el foco. Esto se puede hacer presionando el tabulador hasta llegar a la imagen, porque le hemos dado tabindex="0".

+ +

El evento de click es interesante: parce dependiente del ratón, pero la mayoría de los navegadores activan los controladores de eventos onclick al presionar Enter / Return en un enlace o elemento de formulario que tenga foco, o cuando dicho elemento se toca en un dispositivo de pantalla táctil. Sin embargo, esto no funciona por defecto cuando permites que un evento no enfocable por defecto adquiera el foco usando tabindex; en tales casos, debe detectar específicamente cuándo se presiona esa tecla exacta (consulte Volver a añadir la accesibilidad del teclado).

+ +

¡Pon a prueba tus habilidades

+ +

Has llegado al final de este artículo. ¿Recuerdas la información más importante? Encontrar pruebas para verificar que has retenido esta información antes de continuar en Test your skills: CSS and JavaScript accessibility.

+ +

Resumen

+ +

Esperamos que este artículo te haya brindado una buena cantidad de detalles y comprensión sobre los problemas de accesibilidad relacionados con el uso de CSS y JavaScript en las páginas web.

+ +

¡Siguiente parada, WAI-ARIA!

+ +
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
+ +
+

In this module

+ + +
diff --git a/files/es/learn/accessibility/html/index.html b/files/es/learn/accessibility/html/index.html new file mode 100644 index 0000000000..1b2fb1af25 --- /dev/null +++ b/files/es/learn/accessibility/html/index.html @@ -0,0 +1,588 @@ +--- +title: 'HTML: Una buena base para la accesibilidad' +slug: Learn/Accessibility/HTML +translation_of: Learn/Accessibility/HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}
+ +

Se puede hacer accesible una gran cantidad de contenido web solo asegurándose de que se utilizan los elementos HTML con el propósito correcto todo el tiempo. Este artículo muestra en detalle como HTML puede ser usado para asegurar máxima accesibilidad.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimiento básico de informática, entendimiento básico de HTML (ver Introducción a HTML), y entendimiento de ¿Qué es accesibilidad?.
Objetivo:Familiarizarse con las características de HTML que tiene beneficios de accesibilidad, y como usarla apropiadamente en tus documentos web.
+ +

HTML y accesibilidad

+ +

Cuando aprendas más de HTML — leas más recursos, mires más ejemplos, etc.— vas a seguir viendo un tema en común: la importancia del uso de HTML semántico (a veces llamado POSH, o Plain Old Semantic HTML). Esto significa usar los elementos correctos de HTML para su propósito tanto como sea posible.

+ +

Puedes estarte preguntando ¿por qué es esto tan importante?. Después de todo, puedes usar una combinación de CSS y JavaScript para hacer que casi cualquier elemento HTML se comporte en la forma que tú quieras. Por ejemplo, un botón que reproduzca un vídeo en tu sitio puede estar hecho así:

+ +
<div>Reproducir vídeo</div>
+ +

Pero como verás más adelante, tiene sentido utilizar el elemento correcto para este trabajo:

+ +
<button>Reproducir vídeo</button>
+ +

No solo la etiqueta <button> de HTML ya tiene estilos adecuados por defecto (que probablemente quieras sobrescribir), también están construidos para ser accesibles con el teclado —el usuario puede navegar entre botones usando Tab y activando su selección usando Return o Enter.

+ +

No cuesta más tiempo escribir HTML semántico que (mal) marcado no semántico si lo haces consistentemente desde el comienzo de tu proyecto. Y aun mejor, el marcado semántico tiene otros beneficios más allá de la accesibilidad:

+ +
    +
  1. Fácil desarrollo — como mencionamos, obtienes algunas funcionalidades gratis, y podría decirse que es más fácil de entender.
  2. +
  3. Mejor en móviles — el HTML semántico es probablemente más liviano en tamaño de archivo que el código espagueti no semántico y más fácil de hacer responsivo.
  4. +
  5. Bueno para SEO — Los motores de búsqueda dan más importancia a palabras claves dentro de cabeceras, links, etc., que palabras claves en elementos no semánticos como los <div>, etc., tus documentos serán más fáciles de encontrar por tus clientes.
  6. +
+ +

Continuemos y veamos el HTML accesible en más detalle.

+ +
+

Nota: Es buena idea tener configurado un lector de pantalla en tu computador, para que puedas hacer algunas pruebas de los siguientes ejemplos. Mira nuestra Guía de lectores de pantalla para más detalles.

+
+ +

Buena semántica

+ +

Ya hemos hablado de la importancia de la buena semántica, y por qué deberíamos usar el elemento HTML adecuado para cada caso. Esto no puede ignorarse, ya que es uno de los principales lugares donde la accesibilidad se rompe si no se maneja correctamente.

+ +

En la web, la verdad es que las personas hacen cosas muy extrañas con marcado HTML. Algunos abusos de HTML se deben a prácticas de antaño que no han sido completamente olvidadas y algunas son simplemente ignorancia. Cualquiera que sea el caso, deberías reemplazar ese mal código donde sea que lo veas.

+ +

A veces, no estás en disposición de deshacerte del mal marcado — tus páginas pueden estar generadas por algún tipo de framework del lado del servidor del cual no tienes control total, o puedes tener contenido de terceros en tu página (como banners) sobre los que no tienes control.

+ +

El objetivo no es "todo o nada", pero cada mejora que hagas va a ayudar a la causa de la accesibilidad.

+ +

Contenido textual

+ +

Una de las mejores ayudas de accesibilidad que un usuario lector de pantalla puede tener es una buena estructura de contenido de cabeceras, párrafos, listas, etc. Un  ejemplo de buena semántica puede lucir como el de a continuación:

+ +
<h1>Mi cabecera</h1>
+
+<p>Esta es la primera sección de mi documento.</p>
+
+<p>Voy a agregar también otro párrafo aquí.</p>
+
+<ol>
+  <li>Aquí esta</li>
+  <li>una lista para</li>
+  <li>que la leas</li>
+</ol>
+
+<h2>Mi subtítulo</h2>
+
+<p>Esta es la primera subsección de mi documento. ¡Me encantaría que la gente pudiera leer este contenido!</p>
+
+<h2>Mi 2º subtitulo</h2>
+
+<p>Esta es la segunda subsección de mi documento. Creo que es más interesante que la primera.</p>
+ +

Hemos preparado una versión más larga para que pruebes con un lector de pantalla (ver good-semantics.html). Si tratas de navegar por ella, notaras que es muy fácil:

+ +
    +
  1. El lector de pantalla lee cada cabecera a medida que progresas a través del contenido, notificándote qué es una cabecera, qué es un párrafo, etc.
  2. +
  3. Se detiene después de cada elemento, dejándote ir a un ritmo que sea cómodo para ti.
  4. +
  5. Puedes saltar al siguiente/anterior encabezado en muchos lectores de pantalla.
  6. +
  7. También puedes tener una lista de todos los encabezados en muchos lectores de pantalla, permitiéndote usarlos como una tabla de contenidos para encontrar contenido específico.
  8. +
+ +

Las personas a veces escriben encabezados, párrafos, etc. usando HTML presentacional y saltos de línea, algo como lo siguiente:

+ +
<font size="7">Mi cabecera</font>
+<br><br>
+Esta es la primera sección del documento.
+<br><br>
+Voy a agregar otro párrafo aquí también.
+<br><br>
+1. Aquí esta
+<br><br>
+2. una lista para
+<br><br>
+3. que la leas
+<br><br>
+<font size="5">Mi subtitulo</font>
+<br><br>
+Esta es la primera subsección de mi documento. ¡Me encantaría que la gente pudiera leer este contenido!
+<br><br>
+<font size="5">Mi 2º subtitulo</font>
+<br><br>
+Esta es la segunda subsección de mi documento. Creo que es más interesante que la primera.
+ +

Si pruebas nuestra versión extendida con un lector de pantalla (ver bad-semantics.html), no vas a tener una buena experiencia: el lector de pantalla no tiene nada que usar como señal, por lo que no podrás tener una tabla de contenidos útil y toda la página se ve como un solo bloque gigante, así que solo se lee de una vez, todo de una vez.

+ +

Hay otros problemas más allá de la accesibilidad: es más difícil aplicar estilo al contenido con CSS o manipularlo con JavaScript, por ejemplo, porque no hay elementos para usarlos como selectores.

+ +

Usar lenguaje claro

+ +

El lenguaje que usas también puede afectar la accesibilidad. En general deberías usar lenguaje claro que no sea demasiado complejo y no usar innecesariamente jerga o palabras extrañas. Esto no solo beneficia a las personas con discapacidades cognitivas u otras: beneficia a los lectores para quienes el texto no está escrito en su lengua materna, personas más jóvenes... ¡todo el mundo, de hecho! Aparte de esto, deberías evitar usar lenguaje y caracteres que no se puede leen claramente por un lector de pantalla. Por ejemplo:

+ + + +

Disposiciones de página

+ +

Antiguamente la gente solía crear diseños de página usando tablas HTML, usando diferentes celdas de tabla para contener el encabezado, pie de página, barra lateral, columna de contenido principal, etc. Esto no es una buena idea porque un lector de pantalla probablemente dará como resultado lecturas confusas, especialmente si el diseño es complejo y tiene muchas tablas anidadas.

+ +

Prueba nuestro ejemplo table-layout.html, que tiene este código:

+ +
<table width="1200">
+      <!-- main heading row -->
+      <tr id="heading">
+        <td colspan="6">
+
+          <h1 align="center">Header</h1>
+
+        </td>
+      </tr>
+      <!-- nav menu row  -->
+      <tr id="nav" bgcolor="#ffffff">
+        <td width="200">
+          <a href="#" align="center">Home</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Our team</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Projects</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Contact</a>
+        </td>
+        <td width="300">
+          <form width="300">
+            <input type="search" name="q" placeholder="Search query" width="300">
+          </form>
+        </td>
+        <td width="100">
+          <button width="100">Go!</button>
+        </td>
+      </tr>
+      <!-- spacer row -->
+      <tr id="spacer" height="10">
+        <td>
+
+        </td>
+      </tr>
+      <!-- main content and aside row -->
+      <tr id="main">
+        <td id="content" colspan="4" bgcolor="#ffffff">
+
+          <!-- main content goes here -->
+        </td>
+        <td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
+          <h2>Related</h2>
+
+          <!-- aside content goes here -->
+
+        </td>
+      </tr>
+      <!-- spacer row -->
+      <tr id="spacer" height="10">
+        <td>
+
+        </td>
+      </tr>
+      <!-- footer row -->
+      <tr id="footer" bgcolor="#ffffff">
+        <td colspan="6">
+          <p>©Copyright 2050 by nobody. All rights reversed.</p>
+        </td>
+      </tr>
+    </table>
+ +

Si intentas navegar por él con un lector de pantalla, probablemente te dirá que hay una tabla para mirar (aunque algunos lectores de pantalla pueden adivinar la diferencia entre diseños con tablas y tablas de datos). Luego, probablemente (dependiendo del lector de pantalla que estés usando) tendrás que entrar en la tabla como objeto y mirar sus características por separado, y luego salir de la tabla nuevamente para continuar navegando por el contenido.

+ +

Los diseños con tablas son una reliquia del pasado: tenían sentido cuando la compatibilidad con CSS no estaba muy extendida en los navegadores, pero ahora solo crean confusión para los usuarios de lectores de pantalla. Además, su código fuente requiere más marcado, lo que los hace menos flexibles y más difíciles de mantener. Puedes verificar estas afirmaciones comparando tu experiencia anterior con un ejemplo de estructura de sitio web más moderno, que podría verse así:

+ +
<header>
+  <h1>Header</h1>
+</header>
+
+<nav>
+  <!-- main navigation in here -->
+</nav>
+
+<!-- Here is our page's main content -->
+<main>
+
+  <!-- It contains an article -->
+  <article>
+    <h2>Article heading</h2>
+
+    <!-- article content in here -->
+  </article>
+
+  <aside>
+    <h2>Related</h2>
+
+    <!-- aside content in here -->
+  </aside>
+
+</main>
+
+<!-- And here is our main footer that is used across all the pages of our website -->
+
+<footer>
+  <!-- footer content in here -->
+</footer>
+ +

Si pruebas nuestro ejemplo de estructura más moderna con un lector de pantalla, verás que el marcado de diseño ya no se interpone ni confunde la lectura del contenido. También es mucho más ágil y más pequeño en términos de tamaño de código, lo que significa que el código es más fácil de mantener y menos ancho de banda para que el usuario lo descargue (especialmente para aquellos con conexiones lentas).

+ +

Otra consideración al crear diseños es usar elementos semánticos HTML5 como se ve en el ejemplo anterior (ver secciónado de contenido): puedes crear un diseño usando solo elementos {{htmlelement ("div")}} anidados, pero es mejor usar los elementos de seccionado adecuados para marcar la navegación principal ({{htmlelement ("nav")}}), el pie de página ({{htmlelement ("footer")}}), los bloques de contenido ({{htmlelement ("article")}}), etc. Estos proporcionan semántica adicional para lectores de pantalla (y otras herramientas) para brindar al usuario pistas adicionales sobre el contenido por el que están navegando (consulta Screen Reader Support for new HTML5 Section Elements para hacerte una idea de cómo es el soporte de lectores de pantalla).

+ +
+

Nota: Además de tener una buena semántica y un diseño atractivo, tu contenido debería tener sentido lógico en su orden en el código; siempre puedes colocarlo donde desees usando CSS más adelante, pero deberías tener el orden en el código correcto para empezar, para que lo que se lee a los usuarios de lectores de pantalla tenga sentido.

+
+ +

Controles de interfaz de usuario

+ +

Por controles de interfaz de usuario nos referimos a las partes principales de los documentos web con las que los usuarios interactúan, habitualmente botones, enlaces y controles de formulario. En esta sección, veremos los aspectos básicos de accesibilidad a tener en cuenta al crear dichos controles. Los artículos posteriores sobre WAI-ARIA y multimedia analizarán otros aspectos de la accesibilidad de la interfaz de usuario.

+ +

Un aspecto clave de la accesibilidad de los controles de interfaz de usuario es que, de forma predeterminada, los navegadores permiten que sean manipulados por el teclado. Puedes probar esto usando nuestro ejemplo native-keyboard-accessibility.html (código fuente). Ábrelo en una nueva pestaña y prueba a pulsar la tecla de tabulación; después de algunas pulsaciones, deberías ver que el foco de la pestaña comienza a moverse a través de los diferentes elementos enfocables. Los elementos enfocados reciben un estilo predeterminado resaltado en cada navegador (difiere ligeramente entre diferentes navegadores) para que puedas saber qué elemento está enfocado.

+ +

+ +

Después puedes pulsar Enter / Return para seguir un enlace enfocado o pulsar un botón (hemos incluido algo de JavaScript para que los botones lancen un mensaje), o comenzar a escribir para introducir texto en un campo de texto. Otros elementos de formulario tienen diferentes controles; por ejemplo, el elemento {{htmlelement ("select")}} puede mostrar sus opciones y alternar entre usar las teclas de flecha arriba y abajo.

+ +
+

Note: Diferentes navegadores pueden tener diferentes opciones de control de teclado disponibles. Consulta Using native keyboard accessibility para obtener más detalles.

+
+ +

Básicamente, obtienes este comportamiento gratis, solo con el uso de los elementos apropiados. Por ejemplo:

+ +
<h1>Enlaces</h1>
+
+<p>Esto es un enlace a <a href="https://www.mozilla.org">Mozilla</a>.</p>
+
+<p>Otro enlace, a la <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
+
+<h2>Botones</h2>
+
+<p>
+  <button data-message="Esto es del primer botón">¡Haz clic!</button>
+  <button data-message="Esto es del segundo botón">¡Haz clic aquí también!</button>
+  <button data-message="Esto es del tercer botón">Y aquí!</button>
+</p>
+
+<h2>Formulario</h2>
+
+<form>
+  <div>
+    <label for="nombre">Entra tu nombre:</label>
+    <input type="text" id="nombre" name="nombre">
+  </div>
+  <div>
+    <label for="edad">Entra tu edad:</label>
+    <input type="text" id="edad" name="edad">
+  </div>
+  <div>
+    <label for="humor">Elige tu humor:</label>
+    <select id="humor" name="humor">
+      <option>Feliz</option>
+      <option>Triste</option>
+      <option>Enfadado/a</option>
+      <option>Preocupado/a</option>
+    </select>
+  </div>
+</form>
+ +

Esto significa usar enlaces, botones, elementos y etiquetas de formulario de manera adecuada (incluido el elemento {{htmlelement ("label")}} para los controles de formulario).

+ +

Sin embargo, nuevamente se da el caso de que la gente a veces hace cosas extrañas con HTML. Por ejemplo, a veces ves botones marcados con {{htmlelement ("div")}}s, por ejemplo:

+ +
<div data-message="Esto es del primer botón">¡Haz clic aquí!</div>
+<div data-message="Esto es del segundo botón">¡Haz clic aquñi también!</div>
+<div data-message="Esto es del tercer botón">¡Y aquí!</div>
+ +

Pero no se recomienda el uso de código como este: pierdes inmediatamente la accesibilidad nativa del teclado que habrías tenido si hubieras usado elementos {{htmlelement ("button")}}, y además no obtienes ninguno de los estilos CSS predeterminados que tienen los botones.

+ +

Volver a añadir la accesibilidad del teclado

+ +

Volver a agregar estas ventajas requiere un poco de trabajo (puedes ver un ejemplo en nuestro ejemplo fake-div-buttons.html; consulta también el código fuente). Aquí le hemos dado a nuestros botones <div> falsos la capacidad de enfocarse (incluso a través de la tecla de tabulación) dándole a cada uno el atributo tabindex="0":

+ +
<div data-message="Esto es del primer botón" tabindex="0">¡Haz clic aquí!</div>
+<div data-message="Esto es del segundo botón" tabindex="0">¡Haz clic aquí también!</div>
+<div data-message="Esto es del tercer botón" tabindex="0">¡Y aquí!</div>
+ +

Básicamente, el atributo {{htmlattrxref("tabindex")}} está destinado principalmente a permitir que los elementos tabulables tengan un orden de tabulación personalizado (especificado en orden numérico positivo), en lugar de simplemente tabularlos en su orden de origen predeterminado. Casi siempre es una mala idea, ya que puede causar una gran confusión. Úsalo solo si realmente lo necesitas; por ejemplo, si el diseño muestra las cosas en un orden visual muy diferente al código fuente, y deseas que las cosas funcionen de manera más lógica. Hay otras dos opciones para tabindex:

+ + + +

Si bien la adición anterior nos permite tabular los botones, no nos permite activarlos a través de la tecla Enter / Return. Para hacer eso, hemos tenido que agregar el siguiente truco en JavaScript:

+ +
document.onkeydown = function(e) {
+  if(e.keyCode === 13) { // La tecla Enter/Return
+    document.activeElement.click();
+  }
+};
+ +

Aquí agregamos un "listener" (oyente) al objeto document para detectar cuándo se ha presionado una tecla en el teclado. Comprobamos qué botón se presionó mediante la propiedad keyCode del objeto de evento; si es el código clave que coincide con Return / Enter, ejecutamos la función almacenada en el manejador onclick del botón usando document.activeElement.click(). activeElement nos da el elemento que está actualmente enfocado en la página.

+ +

Esta es mucho trabajo extra para volver a incorporar la funcionalidad. Y seguramente surgirán problemas con ella. Es mejor usar el elemento correcto para el trabajo correcto en primer lugar.

+ +

Etiquetas de texto significativas

+ +

Las etiquetas textuales de los controles de la interfaz de usuario son muy útiles para todos los usuarios, pero hacerlas bien es particularmente importante para los usuarios con discapacidades.

+ +

Deberías asegurarte de que las etiquetas de texto de tus botones y enlaces sean comprensibles y distintivas. No uses simplemente "Haz clic aquí" para tus etiquetas, ya que los usuarios de lectores de pantalla a veces obtienen una lista de botones y controles de formulario. La siguiente captura de pantalla muestra nuestros controles enumerados por VoiceOver en Mac.

+ +

Form controls. Click me! button. Click me too! button. And me! button. Fill me in: edit text. Fill me in: edit text. Happy collapsed pop up button. Happy menu item. Sad menu item. Angry menu item. Worried menu item.

+ +

Asegúrate de que tus etiquetas tienen sentido sin su contexto, leídas solas, así como en el contexto del párrafo en que están. Por ejemplo, lo siguiente muestra un buen ejemplo de enlace de texto:

+ +
<p>Las ballenas son criaturas realmente impresionantes. <a href="whales.html">Aprende más sobre las ballenas</a>.</p>
+ +

y esto es un mal texto de enlace:

+ +
<p>Las ballenas son criaturas realmente impresionantes. Para aprender más sobre las ballenas, <a href="whales.html">haz clic aquí</a>.</p>
+ +
+

Note: Encontrarás mucho más sobre la implementación de enlaces y buenas prácticas en nuestro artículo Crear hipervínculos. También encontrarás buenos y malos ejemplos en good-links.html y bad-links.html.

+
+ +

Las etiquetas de formulario también son importantes, para darte una pista sobre lo que necesita introducir en cada campo de formulario. El siguiente parece un ejemplo bastante razonable:

+ +
Entra tu nombre: <input type="text" id="nombre" name="nombre">
+ +

Sin embargo, esto no es tan útil para usuarios con discapacidad. No hay nada en el ejemplo anterior para asociar la etiqueta de forma inequívoca con la entrada del formulario y dejar claro cómo rellenarlo si no puede verlo. Si accedes con algunos lectores de pantalla, es posible que solo se te proporcione una descripción en la línea de "editar texto".

+ +

El siguiente es un ejemplo mucho mejor:

+ +
<div>
+  <label for="combre">Entra tu nombre:</label>
+  <input type="text" id="combre" name="nombre">
+</div>
+ +

Con código como este, la etiqueta estará claramente asociada con la entrada; la descripción se parecerá más a "Entra tu nombre: editar texto".

+ +

+ +

Como ventaja adicional, en la mayoría de los navegadores asociar una etiqueta con una entrada de formulario significa que puedes hacer clic en la etiqueta para seleccionar / activar el elemento del formulario. Esto le da a la entrada un área de impacto más grande, lo que facilita la selección.

+ +
+

Nota: puedes ver algunos ejemplos de buenos y malos formularios en good-form.html y bad-form.html.

+
+ +

Tablas de datos accesibles

+ +

Se puede escribir una tabla de datos básica con un marcado muy simple, por ejemplo:

+ +
<table>
+  <tr>
+    <td>Nombre</td>
+    <td>Edad</td>
+    <td>Género</td>
+  </tr>
+  <tr>
+    <td>Gabriel</td>
+    <td>13</td>
+    <td>Masculino</td>
+  </tr>
+  <tr>
+    <td>Elva</td>
+    <td>8</td>
+    <td>Femenino</td>
+  </tr>
+  <tr>
+    <td>Freida</td>
+    <td>5</td>
+    <td>Femenino</td>
+  </tr>
+</table>
+ +

Pero esto tiene problemas: no hay forma de que un usuario de lector de pantalla asocie filas o columnas como agrupaciones de datos. Para hacer esto, necesita saber cuáles son las filas de encabezado, y si están encabezando filas, columnas, etc. Esto solo se puede hacer visualmente para la tabla anterior (ve a bad-table.html y prueba tú mismo el ejemplo).

+ +

Ahora echa un vistazo a nuestro ejemplo de tabla de bandas punk: aquí puedes ver algunas ayudas de accesibilidad en funcionamiento:

+ + + +

Consulte nuestro artículo sobre funciones avanzadas y accesibilidad de tablas HTML para obtener más detalles sobre las tablas de datos accesibles.

+ +
+

Note: Consulta nuestro artículo Funciones avanzadas de tablas y accesibilidad para ver más detalles sobre tablas de datos accesibles.

+
+ +

Alternativas de texto

+ +

Mientras que el contenido textual es inherentemente accesible, lo mismo no se puede decir del contenido multimedia — el contenido de imagen/video no puede ser visto por personas con discapacidad visual, y el contenido de audio no puede ser escuchado por personas sordas. Cubriremos el contenido de video y audio en detalle en el artículo multimedia accesible más adelante, pero para este artículo veremos la accesibilidad del humilde elemento {{htmlelement("img")}}.

+ +

Tenemos un ejemplo simple, access-image.html, que presenta cuatro copias de la misma imagen:

+ +
<img src="dinosaur.png">
+
+<img src="dinosaur.png"
+     alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
+
+<img src="dinosaur.png"
+     alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth."
+     title="The Mozilla red dinosaur">
+
+
+<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">The Mozilla red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</p>
+
+ +

La primera imagen, cuando la ve un lector de pantalla, realmente no ofrece mucha ayuda al usuario; VoiceOver, por ejemplo, lee "/dinosaur.png, imagen". Lee el nombre del archivo para intentar proporcionar ayuda. En este ejemplo, el usuario al menos sabrá que es un dinosaurio de algún tipo, pero a menudo los archivos pueden cargarse con nombres de archivo generados por la máquina (por ejemplo, de una cámara digital) y estos nombres de archivo probablemente no proporcionarían contexto al contenido de la imagen.

+ +
+

Nota: Es por eso que nunca debes incluir contenido de texto dentro de una imagen: los lectores de pantalla simplemente no pueden acceder a él. También hay otras desventajas: no puedes seleccionarlo y copiarlo / pegarlo. ¡No lo hagas!

+
+ +

Cuando un lector de pantalla encuentra la segunda imagen, lee el atributo alt completo: "Un tiranosaurio rex rojo: un dinosaurio de dos patas erguido como un humano, con brazos pequeños y una cabeza grande con muchos dientes afilados".

+ +

Esto resalta la importancia de no solo usar nombres de archivo significativos en caso de que el texto alternativo no esté disponible, sino también de asegurarse de que el texto alternativo se proporcione en los atributos alt siempre que sea posible. Ten en cuenta que el contenido del atributo alt siempre debe proporcionar una representación directa de la imagen y lo que transmite visualmente. Aquí no se debe incluir ningún conocimiento personal o descripción adicional, ya que no es útil para personas que no se han encontrado con la imagen antes.

+ +

Una cosa a considerar es si tus imágenes tienen significado dentro del contenido, o si son puramente para decoración visual, por lo que no tienen significado. Si son decorativas, es mejor incluirlas en la página como imágenes de fondo CSS.

+ +
+

Note: Lee Imágenes en HTML y Responsive images para obtener mucha más información sobre la implementación de imágenes y buenas prácticas asociadas.

+
+ +

Si deseas proporcionar información contextual adicional, deberías colocarla en el texto que rodea la imagen o dentro de un atributo title, como se muestra a continuación. En este caso, la mayoría de los lectores de pantalla leerán el texto alternativo, el atributo del título y el nombre del archivo. Además, los navegadores muestran el texto del título como información cuando se pasa por encima con el ratón.

+ +

+ +

Echemos otro vistazo al cuarto método:

+ +
<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">The Mozilla red Tyrannosaurus ... </p>
+ +

En este caso, no estamos usando el atributo alt en absoluto; en cambio, hemos presentado nuestra descripción de la imagen como un párrafo de texto normal, le hemos dado un id y luego usamos el atributo aria-labelledby para referirnos a ese id, que hace que los lectores de pantalla usen ese párrafo como texto alternativo o etiqueta para esa imagen. Esto es especialmente útil si desea utilizar el mismo texto como etiqueta para varias imágenes, algo que no es posible con alt.

+ +
+

Note: aria-labelledby es parte de la especificación WAI-ARIA, que permite a los desarrolladores añadir semántica extra a su marcado para mejorar su accesibilidad para lectores de pantalla cuando sea necesario. Para aprender más sobre cómo funciona, lee nuestro artículo WAI-ARIA Basics.

+
+ +

Otros mecanismos de texto alternativo

+ +

Las imágenes también tienen otros mecanismos disponibles para proporcionar texto descriptivo. Por ejemplo, hay un atributo longdesc que apunta a un documento web separado que contiene una descripción ampliada de la imagen, por ejemplo:

+ +
<img src="dinosaur.png" longdesc="dino-info.html">
+ +

Parece una buena idea, especialmente para infografías como gráficos grandes con mucha información que tal vez podría representarse como una tabla de datos accesible (consulte la sección anterior). Sin embargo, longdesc no es compatible de forma consistente con lectores de pantalla, y el contenido es completamente inaccesible para los usuarios que no usan lectores de pantalla. Podría decirse que es mucho mejor incluir la descripción larga en la misma página que la imagen, o vincularla con un enlace normal.

+ +

HTML5 incluye dos elementos nuevos, {{htmlelement("figure")}} y {{htmlelement("figcaption")}}, que se supone que asocian una figura de algún tipo (podría ser cualquier cosa, no necesariamente una imagen) con un pie de figura:

+ +
<figure>
+  <img src="dinosaur.png" alt="El Tyrannosaurus de Mozilla">
+  <figcaption>Un Tyrannosaurus Rex rojo: Un dinosaurio de dos piernas, de pie como un humano, con brazos pequeños y una cabeza grande con un montón de dientes afilados.</figcaption>
+</figure>
+ +

Desafortunadamente, la mayoría de lectores de pantalla aún no parecen asociar los títulos de las figuras con sus figuras, pero la estructura del elemento es útil para dar estilo con CSS, y además proporciona una manera de colocar una descripción de la imagen junto a ella en el código.

+ +

Atributos alt vacíos

+ +
<h3>
+  <img src="article-icon.png" alt="">
+  Tyrannosaurus Rex: el rey de los dinosaurios
+</h3>
+ +

Puede haber ocasiones en las que se incluya una imagen en el diseño de una página, pero su propósito principal sea la decoración visual. Observarás en el ejemplo de código anterior que el atributo alt de la imagen está vacío; esto es para que los lectores de pantalla reconozcan la imagen, pero no intenten describirla imagen (en su lugar, solo dirían "imagen" o algo similar).

+ +

La razón para usar un alt vacío en lugar de no incluirlo es porque muchos lectores de pantalla anuncian la URL completa de la imagen si no se proporciona un alt. En el ejemplo anterior, la imagen actúa como decoración visual del encabezado al que está asociada. En casos como este, y en los casos en los que una imagen es solo decoración y no tiene valor de contenido, debes poner un alt vacío en tus imágenes. Otra alternativa es usar el atributo de rol aria role = "presentation" - esto también evita que los lectores de pantalla lean el texto alternativo.

+ +
+

Note: si es posible, deberías usar CSS para mostrar imágenes que son solo decoración.

+
+ +

Más sobre enlaces

+ +

Los enlaces (el elemento <a> con un atributo href), según cómo se utilicen, pueden ayudar o perjudicar la accesibilidad. De forma predeterminada, los enlaces son accesibles en apariencia. Pueden mejorar la accesibilidad al ayudar a un usuario a navegar rápidamente a diferentes secciones de un documento. También pueden dañar la accesibilidad si se elimina su estilo accesible o si JavaScript hace que se comporten de manera inesperada.

+ +

Estilo de enlace

+ +

De forma predeterminada, los enlaces son visualmente diferentes de otros textos tanto en el color como en la decoración del texto, con enlaces azules y subrayados de forma predeterminada, morados y subrayados si se visitan, y con un anillo de enfoque cuando reciben el foco del teclado.

+ +

El color no debe usarse como el único método para distinguir los enlaces del contenido que no enlaza. El color del texto del enlace, como todo el texto, debe ser significativamente diferente del color de fondo (un contraste de 4.5:1). Además, los enlaces deben ser visualmente significativamente diferentes del texto sin enlaces. Con un requisito de contraste mínimo de 3:1 entre el texto del enlace y el texto circundante y entre los estados predeterminado, visitado y de enfoque / activo, y un contraste de 4:5 entre todos esos colores de estado y el color de fondo.

+ +

Eventos onclick

+ +

A menudo se abusa de las etiquetas de anclaje con el evento onclick para crear pseudo-botones configurando href a "#" o "javascript:void(0)" para evitar que la página se actualice.

+ +

Estos valores provocan un comportamiento inesperado al copiar o arrastrar enlaces, abrir enlaces en una nueva pestaña o ventana, marcar como favoritos y cuando JavaScript todavía se está descargando aparecen errores o está deshabilitado. Esto también transmite una semántica incorrecta a las tecnologías de asistencia (por ejemplo, lectores de pantalla). En estos casos, se recomienda utilizar un {{HTMLElement("button")}} en su lugar. En general, solo debe usar un ancla para la navegación utilizando una URL adecuada.

+ +

Enlaces externos y enlaces a recursos que no son HTML

+ +

Los enlaces que se abren en una nueva pestaña o ventana mediante la declaración target="_blank" y los enlaces cuyo valor href apunta a un recurso de archivo deben incluir un indicador sobre el comportamiento que se producirá cuando se active el enlace.

+ +

Las personas con problemas de baja visión, que navegan con la ayuda de tecnología de lectura de pantalla o que tienen problemas cognitivos pueden confundirse cuando la nueva pestaña, ventana o aplicación se abre inesperadamente. Es posible que versiones antiguas del software de lectura de pantalla ni siquiera anuncien el comportamiento.

+ +

Enlace que abre una nueva pestaña o ventana

+ +
<a target="_blank" href="https://www.wikipedia.org/">Wikipedia (se abre en una nueva ventana)</a>
+ +

Enlace a un recurso que no es HTML

+ +
<a target="_blank" href="2017-annual-report.ppt">Informe anual de 2017 (PowerPoint)</a>
+ +

Si se utiliza un icono en lugar de texto para indicar este tipo de comportamiento de enlaces, asegúrate de que incluya una {{HTMLAttrxRef("alt", "img", "descripción alternativa", "true")}}.

+ + + +

Enlaces de salto

+ +

Un enlace de salto, también conocido como "skipnav", es un elemento que se coloca lo más cerca posible del elemento de apertura {{HTMLElement("body")}} que enlaza con el comienzo del contenido principal de la página. Este enlace permite a las personas evitar el contenido repetido en varias páginas de un sitio web, como el encabezado y la navegación principal.

+ +

Los enlaces de salto son especialmente útiles para las personas que navegan con la ayuda de tecnología de asistencia, como controles de interruptores, comandos de voz o varitas bucales o para la cabeza, con las que el acto de moverse a través de enlaces repetitivos puede ser una tarea laboriosa.

+ + + +

Proximidad

+ +

Si tenemos grandes cantidades de contenido interactivo, incluidas anclas, colocadas muy cerca visualmente entre sí, deben tener espacio insertado para separarlas. Este espaciado es beneficioso para las personas que sufren problemas de control de la motricidad fina y pueden activar accidentalmente el contenido interactivo incorrecto mientras navegan.

+ +

El espaciado se puede crear usando propiedades CSS como {{CSSxRef("margin")}}.

+ + + +

¡Pon a prueba tus habilidades!

+ +

Ha llegado al final de este artículo, pero ¿recuerdas la información más importante? Consulta Test your skills: HTML Accessibility para verificar que has retenido esta información antes de continuar.

+ +

Resumen

+ +

Ahora ya deberías conocer bien la escritura de HTML accesible para la mayoría de las ocasiones. Nuestro artículo de conceptos básicos de WAI-ARIA también llenará algunos vacíos en este conocimiento, pero este artículo se ha ocupado de los conceptos básicos. A continuación, exploraremos CSS y JavaScript, y cómo la accesibilidad se ve afectada por su buen o mal uso.

+ +

{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}

+ +

In this module

+ + diff --git a/files/es/learn/accessibility/index.html b/files/es/learn/accessibility/index.html new file mode 100644 index 0000000000..fc7cdeeb3c --- /dev/null +++ b/files/es/learn/accessibility/index.html @@ -0,0 +1,60 @@ +--- +title: Accesibilidad +slug: Learn/Accessibility +tags: + - ARIA + - Accesibilidad + - Aprender + - Artículos + - Aterrizaje + - CSS + - CodificaciónDeSecuenciasDeComandos + - HTML + - JavaScript + - Principiantes + - modulo +translation_of: Learn/Accessibility +--- +
{{LearnSidebar}}
+ +

Aprender algo de HTML, CSS y JavaScript es útil si deseas convertirte en un desarrollador web, pero tu conocimiento debe ir más allá de simplemente usar esas tecnologías, debes usarlas de manera responsable para maximizar la audiencia de tus sitios web y evitar impedir su uso a nadie. Para lograr esto, debes adherirte a las mejores prácticas generales (que se muestran en los temas de HTML, CSS y JavaScript), pruebas cruzadas del navegador y considerar la accesibilidad desde el principio. En este módulo, cubriremos este último en detalle.

+ +

Prerrequisitos

+ +

Para aprovechar al máximo este módulo, sería una buena idea trabajar al menos en los dos primeros módulos de los temas de HTML, CSS, y JavaScript o quizás mejor, trabajar en las partes relevantes del módulo de accesibilidad como tu trabajas a través de los temas relacionados con la tecnología.

+ +
+

Nota: si está trabajando en una computadora / tableta / otro dispositivo donde no tiene la capacidad de crear sus propios archivos, puede probar la mayoría de los ejemplos de código en un programa de codificación en línea como JSBin o Thimble.

+
+ +

Guías

+ +
+
¿Qué es la accesibilidad?
+
Este artículo inicia el módulo con un buen vistazo a lo que realmente es la accesibilidad: esto incluye qué grupos de personas debemos considerar y por qué, qué herramientas utilizan las diferentes personas para interactuar con la web y cómo podemos hacer que la accesibilidad sea parte de nuestro flujo de trabajo de desarrollo web.
+
HTML:Una buena base para la accesibilidad
+
Se puede hacer accesible una gran cantidad de contenido web simplemente asegurándose de que los elementos HTML concretos se utilizan para un propósito correcto en todo momento. Este artículo analiza en detalle cómo se puede usar HTML para garantizar la máxima accesibilidad.
+
Mejores prácticas en accesibilidad en CSS y JavaScript
+
CSS y JavaScript, cuando se usan correctamente, también tienen el potencial de permitir experiencias web accesibles, pero si se usan mal pueden dañar significativamente la accesibilidad. Este artículo describe algunas de las mejores prácticas de CSS y JavaScript que deben considerarse para garantizar que incluso el contenido complejo sea lo más accesible posible.
+
WAI-ARIA básico
+
Siguiendo con el artículo anterior, a veces puede ser difícil realizar controles complejos de IU que involucren HTML no semántico y contenido dinámico actualizado con JavaScript. WAI-ARIA es una tecnología que puede ayudar a resolver estos problemas agregando más semántica que los navegadores y las tecnologías de asistencia pueden reconocer y utilizar para que los usuarios sepan lo que está sucediendo. Aquí mostraremos cómo usarlo a un nivel básico para mejorar la accesibilidad.
+
Multimedia accesible
+
Otra categoría de contenido que puede crear problemas de accesibilidad es multimedia: el contenido de video, audio e imagen debe contar con alternativas textuales adecuadas para que las tecnologías de asistencia y sus usuarios puedan entenderlos. Este artículo muestra cómo.
+
Accesibilidad móvil
+
Dado que el acceso a la web en dispositivos móviles es tan popular, y que las plataformas populares como iOS y Android tienen herramientas de accesibilidad completas, es importante considerar la accesibilidad de su contenido web en estas plataformas. Este artículo analiza las consideraciones de accesibilidad específicas para dispositivos móviles.
+
+ +

Valoraciones

+ +
+
Resolución de problemas de accesibilidad
+
En la evaluación de este módulo, te presentamos un sitio simple con una serie de problemas de accesibilidad que necesitas diagnosticar y corregir.
+
+ +

Ver también

+ + diff --git a/files/es/learn/accessibility/mobile/index.html b/files/es/learn/accessibility/mobile/index.html new file mode 100644 index 0000000000..4762e5220c --- /dev/null +++ b/files/es/learn/accessibility/mobile/index.html @@ -0,0 +1,346 @@ +--- +title: Mobile accessibility +slug: Learn/Accessibility/Mobile +translation_of: Learn/Accessibility/Mobile +--- +
+
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
+ +

Dado que el acceso a la web en dispositivos móviles es tan popular, y las plataformas populares como iOS y Android tienen herramientas de accesibilidad completas, es importante considerar la accesibilidad de su contenido web en estas plataformas. Este artículo analiza las consideraciones de accesibilidad específicas para dispositivos móviles.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de computación, una comprensión básica de HTML, CSS y JavaScript, y una comprensión de los artículos previos del curso.
Objetivo:Para comprender qué problemas existen con la accesibilidad en dispositivos móviles y cómo superarlos.
+ +

Accessibility on mobile devices

+ +

 

+ +

El estado de accesibilidad, y el soporte para los estándares web en general, es bueno en los dispositivos móviles modernos. Atrás quedaron los días en que los dispositivos móviles utilizaban tecnologías web completamente diferentes para los navegadores de escritorio, lo que obligaba a los desarrolladores a utilizar el rastreo de los navegadores y les servía sitios completamente separados (aunque muchas empresas aún detectan el uso de dispositivos móviles y les ofrecen un dominio móvil separado).

+ +

En estos días, los dispositivos móviles en general pueden manejar sitios web "completos", y las plataformas principales incluso tienen lectores de pantalla incorporados para permitir que los usuarios con discapacidades visuales los utilicen con éxito. Los navegadores móviles modernos tienden a tener un buen soporte para WAI-ARIA, también.

+ +

 

+ +

 

+ +

Para hacer que un sitio web sea accesible y utilizable en dispositivos móviles, solo debe seguir las buenas prácticas generales de diseño web y accesibilidad.

+ +

Hay algunas excepciones que requieren una consideración especial para el móvil; Los principales son:

+ +

 

+ + + +

Resumen de las pruebas del lector de pantalla en Android e iOS

+ +

 

+ +

Las plataformas móviles más comunes tienen lectores de pantalla completamente funcionales. Estos funcionan de la misma manera que los lectores de pantalla de escritorio, excepto que se operan en gran parte mediante gestos táctiles en lugar de combinaciones de teclas.

+ +

Veamos los dos principales: TalkBack en Android y VoiceOver en iOS.

+ +

 

+ +

Android TalkBack

+ +

 

+ +

El lector de pantalla TalkBack está integrado en el sistema operativo Android.

+ +

Para activarlo, seleccione Configuración> Accesibilidad> TalkBack, y luego presione el interruptor deslizante para activarlo. Siga las indicaciones adicionales en pantalla que le presenten.

+ +

Nota: las versiones anteriores de TalkBack están activadas de formas formas ligeramente distintas.

+ +

Cuando TalkBack esté activado, los controles básicos de su dispositivo Android serán un poco diferentes. Por ejemplo:

+ +
    +
  1. Pulsar una aplicación solo lo seleccionará, y el dispositivo leerá qué es la aplicación.
  2. +
  3. Al deslizar hacia la izquierda y hacia la derecha, se moverá entre las aplicaciones o los botones / controles si se encuentra en una barra de control. El dispositivo leerá cada opción.
  4. +
  5. Si toca dos veces en cualquier lugar, se abrirá la aplicación / seleccione la opción.
  6. +
  7. También puede "explorar con un toque": mantenga el dedo presionado sobre la pantalla y arrástrelo, y su dispositivo leerá las diferentes aplicaciones / elementos con los que se mueve.
  8. +
+ +

Si desea desactivar TalkBack:

+ +
    +
  1. Navega a tu aplicación de configuración utilizando los gestos anteriores.
  2. +
  3. Vaya a Accesibilidad> TalkBack.
  4. +
  5. Navegue hasta el interruptor deslizante y actívelo para apagarlo.
  6. +
+ +

Nota: Puede acceder a la pantalla de inicio en cualquier momento deslizando hacia arriba y hacia la izquierda con un movimiento suave. Si tiene más de una pantalla de inicio, puede moverse entre ellos deslizando dos dedos hacia la izquierda y hacia la derecha.

+ +

Para obtener una lista más completa de los gestos de TalkBack, consulte Usar gestos TalkBack.

+ +

Desbloqueo del telefono

+ +

 

+ +

Cuando TalkBack está activado, desbloquear el teléfono es un poco diferente.

+ +

Puede hacer un deslizamiento con dos dedos hacia arriba desde la parte inferior de la pantalla de bloqueo. Si ha establecido un código de acceso o un patrón para desbloquear su dispositivo, se lo dirigirá a la pantalla de entrada correspondiente para ingresarlo.

+ +

También puede explorar tocando para encontrar el botón Desbloquear en la parte inferior central de la pantalla y luego toque dos veces.

+ +

 

+ +

Menús globales y locales

+ +

 

+ +

TalkBack le permite acceder a los menús de contexto global y local, donde quiera que haya navegado en el dispositivo. El primero proporciona opciones globales relacionadas con el dispositivo en su conjunto, y el segundo proporciona opciones relacionadas con la aplicación / pantalla actual en la que se encuentra.

+ +

Para llegar a estos menús:

+ +

 

+ +
    +
  1. Acceda al menú global deslizando rápidamente hacia abajo y luego a la
  2. +
  3. Acceda al menú local deslizando rápidamente hacia arriba y luego a la
  4. +
  5. Desliza el dedo hacia la izquierda y hacia la derecha para alternar entre las diferentes opciones.
  6. +
  7. Una vez que haya seleccionado la opción que desea, haga doble clic para elegir esa opción.
  8. +
+ +

Para obtener detalles sobre todas las opciones disponibles en los menús de contexto global y local, consulte Uso global y local contextual de menús.

+ +

 

+ + + +

 

+ +

Puede usar el menú contextual local mientras está en un navegador web para encontrar opciones para navegar por páginas web usando solo los encabezados, controles de formulario o enlaces, o navegar línea por línea, etc.

+ +

Por ejemplo, con TalkBack activado:

+ +
    +
  1.     Abra su navegador web.
  2. +
  3.     Activar la barra de URL.
  4. +
  5.     Ingrese una página web que tenga muchos encabezados, como la página principal de bbc.co.uk. Para ingresar el texto de la URL: +
      +
    • Seleccione la barra de URL deslizando hacia la izquierda / derecha hasta que llegue a ella, y luego toque dos veces.
    • +
    • Mantenga presionado el teclado virtual hasta que obtenga el carácter que desea y luego suelte el dedo para escribirlo. Repita para cada personaje.
    • +
    • Una vez que hayas terminado, encuentra la tecla Intro y presiónala.
    • +
    +
  6. +
  7.     Desliza el dedo hacia la izquierda y hacia la derecha para moverte entre los diferentes elementos de la página.
  8. +
  9.     Deslice hacia arriba y hacia la derecha con un movimiento suave para ingresar al menú de contenido local.
  10. +
  11.     Deslízate hacia la derecha hasta que encuentres la opción "Encabezados y puntos de referencia".
  12. +
  13.     Pulse dos veces para seleccionarlo. Ahora podrá desplazarse hacia la izquierda y hacia la derecha para moverse entre encabezados y puntos de referencia de ARIA.
  14. +
  15.     Para volver al modo predeterminado, ingrese nuevamente al menú de contexto local deslizando hacia arriba y a la derecha, seleccione "Predeterminado", y luego toque dos veces para activar.
  16. +
+ +

Nota: consulte Empezar en Android con TalkBack para obtener una documentación más completa.

+ +

 

+ +

iOS VoiceOver

+ +

 

+ +

Una versión móvil de VoiceOver está integrada en el sistema operativo iOS.

+ +

Para activarlo, vaya a la aplicación de configuración y seleccione General> Accesibilidad> VoiceOver. Presione el control deslizante VoiceOver para habilitarlo (también verá otras opciones relacionadas con VoiceOver en esta página).

+ +

Una vez que VoiceOver esté habilitado, los gestos de control básico de iOS serán un poco diferentes:

+ +
    +
  1.     Un solo toque hará que se seleccione el elemento que tocas; su dispositivo dirá el elemento que ha tocado.
  2. +
  3.     También puede navegar por los elementos en la pantalla deslizando hacia la izquierda y hacia la derecha para moverse entre ellos, o deslizando el dedo por la pantalla para moverse entre diferentes elementos (cuando encuentra el elemento que desea, puede quitar el dedo para seleccionarlo). ).
  4. +
  5.     Para activar el elemento seleccionado (por ejemplo, abrir una aplicación seleccionada), toque dos veces en cualquier lugar de la pantalla.
  6. +
  7.     Desliza tres dedos para desplazarte por una página.
  8. +
  9.     Toque con dos dedos para realizar una acción relevante para el contexto, por ejemplo, tomar una foto mientras está en la aplicación de la cámara.
  10. +
+ +

Para apagarlo nuevamente, navegue de nuevo a Configuración> General> Accesibilidad> VoiceOver usando los gestos anteriores, y active el control deslizante VoiceOver para desactivarlo.

+ +

 

+ +

Desbloquear el teléfono

+ +

Para desbloquear el teléfono, debe presionar el botón de inicio (o deslizar) de manera normal. Si tiene un código de acceso configurado, puede seleccionar cada número deslizando / deslizando (como se explicó anteriormente) y luego toque dos veces para ingresar cada número cuando haya encontrado el correcto.

+ +

Usando el rotor

+ +

 

+ +

Cuando VoiceOver está activado, tiene una función de navegación llamada Rotor disponible para usted, que le permite elegir rápidamente entre una serie de opciones útiles comunes. Para usarlo:

+ +
    +
  1. Gira dos dedos alrededor de la pantalla como si estuvieras girando un dial. Cada opción se leerá en voz alta a medida que gire más. Puede ir hacia adelante y hacia atrás para recorrer las opciones.
  2. +
  3. Una vez que hayas encontrado la opción que +
      +
    • Suelte los dedos para seleccionarlo.
    • +
    • Si es una opción que puede repetir el valor de (como Volumen o Velocidad de voz), puede deslizar hacia arriba o hacia abajo para aumentar o disminuir el valor del elemento seleccionado.
    • +
    +
  4. +
+ +

Las opciones disponibles en el Rotor son sensibles al contexto; serán diferentes según la aplicación o la vista en la que se encuentre (consulte a continuación un ejemplo).

+ +

 

+ + + +

Vamos a hacer una prueba a navegar con VoiceOver:

+ +
    +
  1. Abra su navegador web.
  2. +
  3. Activar la barra de URL.
  4. +
  5. Ingrese una página web que tenga muchos encabezados, como la página principal de bbc.co.uk. Para ingresar el texto de la URL: +
      +
    • Seleccione la barra de URL deslizando hacia la izquierda / derecha hasta que llegue a ella, y luego toque dos veces.
    • +
    • Para cada personaje, mantenga presionado el teclado virtual hasta que obtenga el carácter que desea y luego suelte el dedo para seleccionarlo. Pulse dos veces para escribirlo.
    • +
    • Una vez que hayas terminado, encuentra la tecla Intro y presiónala.
    • +
    +
  6. +
  7. Desliza el dedo hacia la izquierda y hacia la derecha para moverte entre los elementos de la página. Puede tocar dos veces un elemento para seleccionarlo (por ejemplo, siga un enlace).
  8. +
  9. Por defecto, la opción de Rotor seleccionada será Speaking Rate; actualmente puede deslizar hacia arriba y hacia abajo para aumentar o disminuir la frecuencia de habla.
  10. +
  11. Ahora gire dos dedos alrededor de la pantalla como un cuadrante para mostrar el rotor y muévase entre sus opciones. Aquí hay algunos ejemplos de las opciones disponibles: +
      +
    • Tasa de habla: Cambia la tasa de habla.
    • +
    • Contenedores: muévete entre los diferentes contenedores semánticos de la página.
    • +
    • Encabezados: muévete entre los encabezados de la página.
    • +
    • Enlaces: Mover entre enlaces en la página.
    • +
    • Controles de formulario: muévase entre los controles de formulario en la página.
    • +
    • Idioma: Mover entre diferentes traducciones, si están disponibles.
    • +
    +
  12. +
  13. Seleccionar encabezados. Ahora podrá desplazarse hacia arriba y hacia abajo para moverse entre los encabezados de la página.
  14. +
+ +

Nota: Para obtener una referencia más completa que cubra los gestos de VoiceOver disponibles y otros consejos sobre las pruebas de accesibilidad en iOS, consulte Probar la accesibilidad en su dispositivo con VoiceOver.

+ +

 

+ +

Mecanismos de control

+ +

En nuestro artículo de accesibilidad de CSS y JavaScript, examinamos la idea de eventos que son específicos de un determinado tipo de mecanismo de control (eventos ratón-específicos). Para resumir, esto causa problemas de accesibilidad porque otros mecanismos de control no pueden activar la funcionalidad asociada.

+ +

Como ejemplo, el evento de clic es bueno en términos de accesibilidad: se puede invocar un controlador de eventos asociado haciendo clic en el elemento en el que está configurado el controlador, haciendo tabulaciones en él y presionando Intro / Retorno, o tocándolo en un dispositivo de pantalla táctil. Pruebe nuestro ejemplo simple-button-example.html (véalo en vivo) para ver lo que queremos decir.

+ +

Alternativamente, los eventos específicos del mouse como mousedown y mouseup crean problemas: sus controladores de eventos no pueden invocarse usando controles que no sean del mouse.

+ +

Si intenta controlar nuestro ejemplo de  simple-box-drag.html (ver ejemplo en vivo) con el teclado o el toque, verá el problema. Esto ocurre porque estamos usando un código como el siguiente:

+ +
div.onmousedown = function() {
+  initialBoxX = div.offsetLeft;
+  initialBoxY = div.offsetTop;
+  movePanel();
+}
+
+document.onmouseup = stopMove;
+ +

Para habilitar otras formas de control, debe usar eventos diferentes pero equivalentes; por ejemplo, los eventos táctiles funcionan en dispositivos con pantalla táctil:

+ +
div.ontouchstart = function(e) {
+  initialBoxX = div.offsetLeft;
+  initialBoxY = div.offsetTop;
+  positionHandler(e);
+  movePanel();
+}
+
+panel.ontouchend = stopMove;
+ +

Hemos proporcionado un ejemplo sencillo que muestra cómo usar el mouse y los eventos táctiles juntos multi-control-box-drag.html (ver ejemplo en vivo).

+ +

Nota: También puede ver ejemplos totalmente funcionales que muestran cómo implementar diferentes mecanismos de control en Implementando mecanismos de control de juego.

+ +

Diseño de respuesta

+ +

El diseño de respuesta es la práctica de hacer que sus diseños y otras características de sus aplicaciones cambien dinámicamente dependiendo de factores como el tamaño de la pantalla y la resolución, para que sean utilizables y accesibles para usuarios de diferentes tipos de dispositivos.

+ +

En particular, los problemas más comunes que deben abordarse para dispositivos móviles son:

+ +

 

+ + + +

Nota: No proporcionaremos una discusión completa de las técnicas de diseño receptivo aquí, ya que están cubiertas en otros lugares alrededor de MDN (vea los enlaces anteriores).

+ +

Consideraciones específicas para móviles

+ +

Hay otros aspectos importantes a tener en cuenta al hacer que los sitios sean más accesibles en dispositivos móviles. Hemos enumerado un par aquí, pero agregaremos más cuando pensemos en ellos.

+ +

No deshabilitar el zoom

+ +

Usando viewport, es posible deshabilitar el zoom, usando un código como este en su {{htmlelement("head")}}:

+ +
<meta name="viewport" content="user-scalable=no">
+ +

Nunca debe hacer esto si es posible: muchas personas confían en el zoom para poder ver el contenido de su sitio web, por lo que eliminar esta funcionalidad es una muy mala idea. Hay ciertas situaciones en las que el zoom podría romper la interfaz de usuario; en tales casos, si cree que necesita deshabilitar el zoom, debe proporcionar algún otro tipo de equivalente, como un control para aumentar el tamaño del texto de una manera que no rompa su interfaz de usuario.

+ +

Mantener los menús accesibles.

+ +

 

+ +

Debido a que la pantalla es mucho más estrecha en los dispositivos móviles, es muy común utilizar consultas de medios y otras tecnologías para hacer que el menú de navegación se reduzca a un pequeño icono en la parte superior de la pantalla, que se puede presionar para mostrar el menú solo si es necesario - cuando el sitio se ve en el móvil. Esto suele representarse mediante un icono de "tres líneas horizontales" y, por lo tanto, el patrón de diseño se conoce como "menú de hamburguesas".

+ +

Al implementar un menú de este tipo, debe asegurarse de que el control para revelarlo sea accesible mediante los mecanismos de control apropiados (normalmente, toque para dispositivos móviles), como se explica en {{ anch("Control mechanisms" )}}, y que el resto La página se aleja o se oculta de alguna manera mientras se accede al menú, para evitar confusiones al navegar.

+ +

Haga clic aquí para un buen ejemplo de menú de hamburguesa.

+ +

Entrada de usuario

+ +

 

+ +

En los dispositivos móviles, el ingreso de datos tiende a ser más molesto para los usuarios que la experiencia equivalente en computadoras de escritorio. Es más conveniente escribir texto en las entradas de formulario utilizando un teclado de computadora de escritorio o portátil que un teclado virtual de pantalla táctil o un pequeño teclado físico móvil.

+ +

Por esta razón, vale la pena intentar minimizar la cantidad de escritura necesaria. Como ejemplo, en lugar de hacer que los usuarios completen el título de su trabajo cada vez que usan una entrada de texto regular, podría ofrecer un menú {{htmlelement ("select")}} que contenga las opciones más comunes (que también ayuda a mantener la coherencia en entrada de datos), y ofrece una opción "Otro" que muestra un campo de texto para escribir cualquier valor atípico. Puedes ver un ejemplo simple de esta idea en acción en common-job-types.html (ver el common jobs ejemplo en vivo).

+ +

También vale la pena considerar el uso de los tipos de entrada de formulario HTML5, así como la fecha en las plataformas móviles, ya que ambos los manejan bien: tanto Android como iOS, por ejemplo, muestran widgets utilizables que se adaptan bien a la experiencia del dispositivo. Ver html5-form-examples.html para algunos ejemplos (ver el ejemplo de formulario en vivo en HTML5) — intenta cargarlos y manipularlos en dispositivos móviles. Por ejemplo:

+ + + +

If you want to provide a different solution for desktops, you could always serve different markup to your mobile devices using feature detection. See input types for raw information on detecting different input types, and also check out our feature detection article for much more information.

+ +

Resumen

+ +

En este artículo, le proporcionamos algunos detalles sobre problemas comunes comunes relacionados con la accesibilidad móvil y cómo superarlos. También lo llevamos a través del uso de los lectores de pantalla más comunes para ayudarlo en las pruebas de accesibilidad.

+ +

Ver también

+ + + +
{{PreviousMenuNext("Learn/Accessibility/Multimedia","Learn/Accessibility/Accessibility_troubleshooting", "Learn/Accessibility")}}
+ +
+

En este módulo

+ + +
+
diff --git "a/files/es/learn/accessibility/qu\303\251_es_la_accesibilidad/index.html" "b/files/es/learn/accessibility/qu\303\251_es_la_accesibilidad/index.html" new file mode 100644 index 0000000000..e92994e37c --- /dev/null +++ "b/files/es/learn/accessibility/qu\303\251_es_la_accesibilidad/index.html" @@ -0,0 +1,211 @@ +--- +title: ¿Qué es la accesibilidad? +slug: Learn/Accessibility/Qué_es_la_accesibilidad +translation_of: Learn/Accessibility/What_is_accessibility +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}
+ +

En este artículo se inicia el módulo con una explicación ampliada sobre qué es la accesibilidad. Esta visión general incluye qué grupos de personas necesitamos tener en cuenta y por qué, qué herramientas utilizan estas personas para interactuar con la web y cómo podemos hacer que la accesibilidad sea parte de nuestro flujo de trabajo de desarrollo web.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática y de lenguaje HTML y CSS.
Objetivo:Familiarizarse con la accesibilidad (qué es y cómo te afecta como desarrollador web).
+ +

¿Qué es la accesibilidad?

+ +

La accesibilidad hace que tus sitios web puedan ser utilizados por el mayor número de personas posible. Tradicionalmente, se ideó para las personas con discapacidad, pero la creación de sitios accesibles también beneficia a otros grupos, como los que utilizan los dispositivos móviles o los que tienen conexiones de red lentas.

+ +

También podrías pensar en la accesibilidad como una forma de tratar a todos por igual y darles las mismas oportunidades, sin importar su capacidad o circunstancias. Al igual que es injusto excluir a alguien de un edificio porque vaya en silla de ruedas (generalmente, los edificios públicos modernos tienen rampas o ascensores), tampoco es correcto excluir a alguien de un sitio web porque tenga una discapacidad visual. Todos somos diferentes, pero todos somos humanos, y por lo tanto tenemos los mismos derechos.

+ +

Por eso debemos hacer las cosas accesibles. En algunos países es obligado por ley proporcionar sitios web accesibles, lo que te puede abrir algunos mercados importantes que de otra manera no serían capaces de utilizar tus servicios o comprar tus productos.

+ +

Crear sitios web accesibles nos beneficia a todos:

+ + + +

¿Con que tipo de discapacidades nos encontraremos?

+ +

Las personas con discapacidad son tan diversas como las personas sin discapacidad, y también lo son sus discapacidades. La clave está en pensar más allá de tu ordenador y en cómo utilizas la web y empezar a aprender acerca de cómo otros la utilizan. Tú no eres tus usuarios. A continuación explicaremos los principales tipos de discapacidad que vamos a considerar, junto con las herramientas especiales que se utilizan para acceder al contenido web (conocidas como tecnologías de apoyo o AT, de assistive technologies).

+ +
+

Nota: La hoja informativa sobre discapacidad y salud de la Organización Mundial de la Salud establece que «Más de mil millones de personas, aproximadamente el 15% de la población mundial, tienen alguna forma de discapacidad» y «Entre 110 millones y 190 millones de adultos tienen dificultades funcionales significativas».

+
+ +

Personas con discapacidad visual

+ +

Las personas con discapacidad visual son aquellas con ceguera, poca visión o daltonismo. Muchas personas con discapacidad visual utilizan amplificadores de pantalla que consisten en lupas físicas o funciones de zoom por software. La mayoría de los navegadores y sistemas operativos de hoy en día tienen instaladas funciones de zoom. Algunos usuarios confían en los lectores de pantalla, un software que lee en voz alta los textos digitales. Algunos ejemplos de lectores de pantalla incluyen:

+ + + +

Familiarizarse con los lectores de pantalla puede ser útil, así como configurar un lector de pantalla y jugar con él para aprender cómo funciona. Consulta nuestra guía de lectores de pantalla de prueba para la navegación cruzada para obtener más detalles sobre su uso. El vídeo siguiente proporciona un breve ejemplo de cómo es esta experiencia.

+ +

{{EmbedYouTube("IK97XMibEws")}}

+ +

En términos de estadística, la Organización Mundial de la Salud estima que «Alrededor de 285 millones de personas de todo el mundo tienen discapacidad visual: 39 millones son ciegas y 246 tienen visión reducida.» (Véase Discapacidad visual y ceguera). Esa es una población grande y significativa de usuarios (casi la misma población de los Estados Unidos de América), a la que simplemente perderás porque tu sitio web no está codificado correctamente.

+ +

Personas con discapacidades auditivas

+ +

También conocidas como personas con trastornos auditivos o personas sordas. Son un grupo de personas con niveles de audición bajos o nulos. Las personas con discapacidad auditiva usan AT (véase Dispositivos de asistencia para personas con trastornos auditivos, de voz, del habla o del lenguaje), pero en realidad no hay AT específicos para el uso del ordenador/web.

+ +

Hay, sin embargo, técnicas específicas para ofrecer alternativas textuales a contenidos de audio, que van desde simples transcripciones hasta pistas de texto (es decir, subtítulos) que se pueden mostrar junto con el vídeo. Pero lo veremos más adelante.

+ +

Las personas con discapacidad auditiva también representan una importante base de usuarios: «466 millones de personas en todo el mundo tienen pérdida auditiva discapacitante», dice la hoja informativa sobre Sordera y pérdida auditiva de la Organización Mundial de la Salud.

+ +

Personas con discapacidad motriz

+ +

Estas personas tienen discapacidades relativas a la movilidad, que pueden implicar problemas puramente físicos (como la pérdida de una extremidad o la parálisis) o trastornos neurológicos/genéticos que conducen a la debilidad o pérdida de control en las extremidades. Algunas personas simplemente pueden tener dificultades a la hora de mover el ratón, mientras que otras podrían verse más gravemente afectadas, tal vez estén paralizadas y necesiten utilizar un puntero de cabeza para interactuar con los ordenadores.

+ +

Este tipo de discapacidad se da principalmente por la vejez, y no por cualquier trauma o condición específica, y también podría resultar de limitaciones en el hardware (algunos usuarios podrían no tener un ratón).

+ +

La forma en que esto afecta al desarrollo web es el requisito de que los controles sean accesibles por el teclado. Hablaremos de la accesibilidad del teclado en artículos posteriores de este módulo, pero te recomendamos probar algunos sitios web utilizando solo el teclado para ver cómo funcionan. Por ejemplo, ¿se puede utilizar la tecla de tabulación para moverse entre los diferentes controles de un formulario web? Puedes encontrar más detalles sobre los controles del teclado en nuestro apartado Accesibilidad desde el teclado.

+ +

Si nos basamos en las estadísticas, vemos que un número significativo de personas tienen problemas de movilidad. Los Centros para el Control y la Prevención de Enfermedades de Discapacidad y Funcionalidad (Adultos a partir de 18 años no registrados en una institución) de los Estados Unidos informan de que el porcentaje de adultos con alguna disfunción física en los EUA es del 16,1%.

+ +

Personas con discapacidad cognitiva

+ +

La discapacidad cognitiva engloba una amplia gama de discapacidades, desde las personas que presentan las capacidades intelectuales más limitadas hasta toda la población que tiene problemas a la hora de recordar por los síntomas de la edad. Este amplio abanico incluye a las personas con enfermedades mentales como la depresión y la esquizofrenia. También incluye a personas con dificultades de aprendizaje, como la dislexia y el trastorno por déficit de atención con hiperactividad. Es importante destacar que, aunque hay una gran diversidad dentro de las definiciones clínicas de alteraciones cognitivas, las personas que las experimentan tienen un conjunto común de problemas funcionales, que incluye dificultades a la hora de entender los contenidos, recordar cómo completar las tareas y confusión ante páginas web diseñadas de forma incoherente.

+ +

Una buena base de accesibilidad para personas con deficiencias cognitivas incluye:

+ + + +

Observaciones

+ + + +

Implementa la accesibilidad en tu proyecto

+ +

Un mito común de la accesibilidad es que se trata de un «extra añadido» que encarece tu proyecto. Este mito puede resultar cierto si:

+ + + +

Sin embargo, si se tiene en cuenta la accesibilidad desde el inicio de un proyecto, el coste es muy reducido.

+ +

Al planificar tu proyecto, debes tener en cuenta las pruebas de accesibilidad en la fase de pruebas, lo mismo que las pruebas para cualquier otro sector de público objetivo importante (por ejemplo, los navegadores de escritorio o los navegadores para dispositivo móvil). Somete tu proyecto a pruebas desde una etapa temprana y con frecuencia, idealmente con pruebas automatizadas para detectar carencias detectables en la programación, como la falta de textos alternativos en las imágenes o textos de enlace no adecuados (consulta Relaciones entre elementos y contexto). Y haz algunas pruebas con grupos de usuarios con discapacidad para ver cómo se desenvuelven con las características más complejas de tu sitio web. Por ejemplo:

+ + + +

Puedes y debes tener en cuenta las áreas potencialmente problemáticas del contenido que habrá que modificar para proporcionarles accesibilidad, asegúrate de que se prueban a fondo y piensa en soluciones/alternativas. El contenido textual (como veremos en el próximo artículo) es fácil, pero ¿qué pasa con el contenido multimedia y con esos fantásticos gráficos 3D? Echa un ojo al presupuesto del proyecto y piensa en soluciones que estén a tu disposición para convertir tales contenidos en accesibles. Transcribir todos tus archivos multimedia es una opción posible, aunque cara.

+ +

Seamos realistas. El «100% de accesibilidad» es un ideal inalcanzable, ya que siempre te encontrarás con algún tipo de caso límite en que un determinado usuario encuentra ciertos contenidos difíciles de usar, pero debes hacer todo lo que puedas. Si planeas incluir un gráfico 3D circular creado a partir de WebGL, es posible que desees incluir una tabla de datos como una representación alternativa accesible. O bien puedes simplemente incluir la tabla y deshacerte del gráfico circular 3D (todo el mundo puede acceder a la tabla, su codificación resulta más simple, y además consume menos recursos de la CPU y es de mantenimiento más fácil.

+ +

Por otro lado, si trabajas en un sitio web de una galería que muestra obras de arte interesantes en 3D, no sería razonable esperar que cada obra de arte sea perfectamente accesible para las personas con discapacidad visual, ya que se trata de un medio completamente visual.

+ +

Para demostrar que te importa y que has pensado en la accesibilidad, publica una declaración de accesibilidad en la página web que explique tu política de accesibilidad y los pasos realizados para hacer que el sitio web sea accesible. Si alguien se queja de que tiene un problema de accesibilidad: inicia un diálogo con ellos, se empático y toma las medidas razonables para tratar de solucionar el problema.

+ +
+

Nota: Nuestro artículo sobre Cómo afrontar los problemas de accesibilidad más comunes expone los detalles de accesibilidad que es necesario tener más en cuenta.

+
+ +

En resumen:

+ + + +

Directrices de accesibilidad y la ley

+ +

Hay numerosas listas de control y conjuntos de directrices en las cuales basar las pruebas de accesibilidad, por lo que podría parecer abrumador a primera vista. Nuestro consejo es que te familiarices con las áreas básicas en las que te interesa centrarte, así como que comprendas las estructuras de alto nivel de las directrices que son más relevantes para ti.

+ + + +

Así, mientras que la WCAG es un conjunto de directrices, tu país probablemente tiene leyes que rigen la accesibilidad web, o al menos la accesibilidad de los servicios disponibles para el público (que incluyen sitios web, televisión, espacios físicos, etc.). Conocer estas leyes puede resultarte útil. Si no te preocupas por comprobar que tu contenido sea accesible, podrías incurrir en alguna responsabilidad legal, si la gente se queja.

+ +

Suena serio, pero en realidad solo tienes que considerar la accesibilidad como la prioridad principal a la hora de desarrollar tu web, como ya hemos dicho. En caso de duda, asesórate por un abogado cualificado. Y como nosotros no lo somos, no vamos a ofrecer más consejos sobre este tema.

+ +

API de accesibilidad

+ +

Los navegadores web hacen uso de API de accesibilidad especiales (proporcionadas por el sistema operativo subyacente) que exponen información útil para las tecnologías de asistencia (AT, assistive technologies): la mayoría de AT tienden a utilizar información semántica, por lo que esta información no incluye información de estilo o JavaScript. Esta información se estructura en un árbol de datos, denominado árbol de accesibilidad.

+ +

Los diferentes sistemas operativos disponen de diferentes API de accesibilidad:

+ + + +

Cuando la información semántica nativa proporcionada por los elementos HTML de tus aplicaciones web falla, puedes complementarlo con características de la especificación WAI-ARIA, que añaden información semántica al árbol para mejorar la accesibilidad. Puedes aprender más acerca de WAI-ARIA en nuestro artículo de fundamentos WAI-ARIA.

+ +

Resumen

+ +

Este artículo debería haber dado una descripción detallada sobre la accesibilidad, mostrar por qué es importante y enseñar cómo puede encajar en tu flujo de trabajo. Ahora también deberías tener sed de conocimientos sobre los detalles de implementación que hacen que los sitios sean accesibles. Comenzaremos con esto en la sección siguiente, observando por qué HTML es una buena base para la accesibilidad.

+ +

{{NextMenu("Learn/Accessibility/HTML", "Learn/Accessibility")}}

+ +

En este módulo

+ + + +

Véase también

+ + diff --git a/files/es/learn/aprender_y_obtener_ayuda/index.html b/files/es/learn/aprender_y_obtener_ayuda/index.html new file mode 100644 index 0000000000..a7f06d90d8 --- /dev/null +++ b/files/es/learn/aprender_y_obtener_ayuda/index.html @@ -0,0 +1,321 @@ +--- +title: Aprender y obtener ayuda +slug: Learn/Aprender_y_obtener_ayuda +tags: + - Aprender + - Desarrollo web + - Principiante + - conseguir ayuda + - obtener ayuda +translation_of: Learn/Learning_and_getting_help +--- +

{{learnsidebar}}

+ +

Es genial que dediques algo de tiempo a aprender un nuevo conjunto de habilidades, pero puedes emplear algunas buenas prácticas que harán que tu aprendizaje sea más efectivo. También hay momentos en los que te atascarás y te sentirás frustrado, incluso los desarrolladores web profesionales se sienten así regularmente, y vale la pena conocer las formas más efectivas de tratar de obtener ayuda para que puedas progresar en tu trabajo. Este artículo proporciona algunos consejos y sugerencias en ambas áreas que te ayudarán a obtener más provecho del aprendizaje del desarrollo web, así como una lectura adicional para que puedas obtener más información sobre cada subtema si lo deseas.

+ +

Aprendizaje efectivo

+ +

Sigamos adelante y pensemos en un aprendizaje efectivo.

+ +

Diferentes métodos de aprendizaje

+ +

Es interesante considerar que hay dos formas principales en las que tu cerebro aprende cosas — el aprendizaje enfocado y el aprendizaje difuso:

+ + + +

A partir de los estudios que los neurocientíficos han realizado sobre la actividad cerebral, hemos descubierto que realmente no se puede participar en ambas formas de aprendizaje, o de pensamiento simultáneamente. Entonces, ¿cuál debes elegir? Puedes pensar que el aprendizaje enfocado es mejor para estudiar, pero en realidad, ambos son muy importantes.

+ +

El pensamiento enfocado es excelente para concentrarte mucho en temas específicos, profundizar en la resolución de problemas y mejorar tu dominio de las técnicas requeridas, fortaleciendo las vías neuronales en tu cerebro donde se almacena esa información. Sin embargo, no es muy bueno para entender "el panorama general" y desbloquear nuevas vías neuronales cuando intentas comprender nuevos temas o resolver nuevos problemas que no has encontrado antes.

+ +

Para eso, necesitas un pensamiento difuso. Esto es lo opuesto al enfoque — dejas que tu cerebro divague por el paisaje más amplio, buscando conexiones que no tenías antes, tocando cosas nuevas (o nuevas combinaciones de cosas) en las que luego puedes concentrarte para fortalecerlas y empezar a entender realmente lo que significan.

+ +

Es por eso que generalmente es bueno leer primero un material introductorio para obtener una comprensión de alto nivel de un área, antes de saltar a los detalles específicos.

+ +

También es la razón por la que, a veces, puedes quedar realmente atrapado en un problema, pero luego averiguar la respuesta cuando vas a tomar un café (o a caminar). Podrías:

+ +
    +
  1. Saber cómo solucionar el problema A con la herramienta A.
  2. +
  3. Saber cómo solucionar el problema B con la herramienta B.
  4. +
  5. No saber cómo solucionar el problema C.
  6. +
+ +

Supongamos que te enfocas en el problema C por un tiempo y te frustras porque no puedes encontrar la solución para resolverlo. Pero luego, después de caminar para tomar un poco de aire fresco, es posible que descubras que, mientras tu mente divaga, de repente estableces una conexión entre la herramienta A y la herramienta B, ¡y te das cuenta de que las puedes usar juntas para solucionar el problema C! No siempre es así de simple, pero también es sorprendente cuántas veces sucede. Esto también resalta la importancia de tomar descansos regulares cuando estás estudiando frente a la computadora.

+ +

Diferentes materiales de aprendizaje

+ +

También vale la pena mirar los diferentes tipos de materiales de aprendizaje disponibles, para ver cuáles son los más efectivos para que aprendas.

+ +

Artículos textuales

+ +

Encontrarás muchos artículos escritos en la web para enseñarte sobre diseño web. Como la mayor parte de este curso, por ejemplo. Algunos de los artículos serán tutoriales, para enseñarte una determinada técnica o concepto importante (como "aprender a crear un reproductor de video" o "Aprender el modelo de cajas CSS"), y algunos de los artículos serán material de referencia, para permitirte recordar detalles que hayas olvidado (como "¿cuál es la sintaxis de la propiedad background de CSS"?)

+ +

MDN Web Docs es muy bueno para ambos tipos — el área en la que te encuentras actualmente es excelente para aprender técnicas y conceptos, y también tenemos varias secciones de referencia gigantes que te permiten buscar cualquier sintaxis que no puedas recordar.

+ +

También hay varios otros recursos excelentes en la web, algunos de los cuales mencionaremos a continuación.

+ +
+

Nota: el texto anterior debería haberte proporcionado un dato importante: ¡no se espera que recuerdes todo! Los desarrolladores web profesionales todo el tiempo usan herramientas como MDN Web Docs para buscar cosas que han olvidado. Como descubrirás a lo largo de estas líneas, aprender desarrollo web tiene más que ver con la resolución de problemas y patrones de aprendizaje que con el aprendizaje de muchas sintaxis.

+
+ +

Videos

+ +

También hay una serie de sitios que tienen contenido de aprendizaje de video en ellos. YouTube es obvio, con canales como Mozilla Layout Land, MozillaDeveloper y Google ChromeDevelopers que proporcionan muchos útiles videos. Muchas personas prefieren artículos textuales para un aprendizaje más profundo y material de referencia, y videos para explicaciones rápidas de conceptos y nuevas características, pero realmente depende de ti lo que prefieras aprender. Aquí no hay una respuesta correcta e incorrecta.

+ +

Código de juegos interactivos

+ +

Posiblemente seas el tipo de persona que prefiere instrucciones mínimas y preferirías saltar directamente y comenzar a jugar con el código. Este también es un enfoque razonable, y algunos sitios de aprendizaje tienden a favorecerlo. Codecademy, por ejemplo, es un sitio de aprendizaje donde los tutoriales consisten principalmente en editores de códigos interactivos en los que debes escribir directamente el código y ver si se logró el resultado deseado.

+ +

Muchas páginas de referencia de documentos web de MDN también proporcionan ejemplos interactivos, donde puedes modificar el código y ver cómo cambia el resultado en vivo. Y tampoco hay nada de malo en crear tus propios ejemplos de código en tu computadora o en un editor de código en línea como JSBin, Codepen o Glitch. De hecho, ¡te invitarán a usarlos como parte de este curso cuando estés aprendiendo!

+ +
+

Nota: Los editores de código en línea también son realmente útiles para compartir el código que has escrito, por ejemplo, si estás colaborando en el aprendizaje con otra persona que no se encuentra en la misma ubicación o se lo envías a alguien para pedir ayuda con eso. Puedes compartir la dirección web del ejemplo con ellos para que puedan verlo y ayudarte.

+
+ +
+

Nota: Es posible que prefieras un método de aprendizaje sobre los demás, pero, de manera realista, probablemente terminarás con un enfoque híbrido. Y probablemente se te ocurran otros métodos además de los tres que cubrimos anteriormente.

+
+ +

Haz un plan

+ +

Es una buena idea crear un plan para ayudarte a lograr lo que quieres conseguir a través de tu aprendizaje.

+ +

Una declaración de objetivos

+ +

Suena tonto, pero ¿por qué no comenzar con una sola oración que diga lo que quieres lograr? Los siguientes tienen diferentes ámbitos, pero todos son realistas y alcanzables:

+ + + +

Los siguientes no son tan razonables:

+ + + +

¿Qué necesitas para llegar allí?

+ +

Una vez que hayas descrito tu objetivo, es una buena idea investigar qué necesitarás para lograrlo. Por ejemplo:

+ +

Materiales que necesito:

+ + + +

Conocimiento que necesito:

+ + + +

¿Cuánto tiempo y dinero costará?

+ +

Calcula el tiempo y el costo para obtener estas cosas. Si necesitas trabajar para ganar dinero para comprar los materiales requeridos, entonces deberás tener en cuenta el tiempo para hacerlo. Una vez que tengas un estimado del tiempo, puedes comenzar a elaborar un plan para tu vida.

+ +

¿Cuántas horas por semana necesitas invertir?

+ +

Una vez que sepas lo que necesitas hacer y cuánto tiempo crees que te llevará, puedes comenzar a escribir un plan a seguir para lograr tu objetivo. Puede ser tan simple como:

+ +

"Me llevará 500 horas aprender lo que necesito saber, y tengo un año para hacerlo, así que si asumo 2 semanas de vacaciones, tendré que trabajar en esto durante 10 horas por semana. Estoy gratis por las tardes y fines de semana, así que planearé mi tiempo en torno a eso".

+ +

La cantidad de tiempo que puedes dedicar a esto, por supuesto, depende de cuáles sean tus circunstancias. Si estás en la escuela, entonces tienes mucho más tiempo libre que si tienes un trabajo y niños que mantener. Todavía es posible lograr tus objetivos, pero debes ser realista sobre la rapidez con que puedes lograrlo.

+ +

Si estás haciendo un curso colegial o universitario para aprender desarrollo web, entonces la mayor parte de esta planificación la haces tú, ¡qué suerte!

+ +

Cuando hayas elaborado un horario semanal, debes mantener un registro de lo que logras hacer cada semana en una simple hoja de cálculo o incluso en un cuaderno.

+ +

Además, sería una buena idea tener algunos objetivos secundarios resueltos que te permitan realizar fácilmente un seguimiento de dónde te encuentras, por ejemplo:

+ + + +

Sigue pensando en cuánto progreso estás haciendo y ajusta tu plan si es necesario.

+ +

Mantente motivado

+ +

Es difícil mantenerte motivado, especialmente si estás tratando de aprender una habilidad compleja como la programación o el desarrollo web. Lo que sigue son algunos consejos para mantenerte motivado y seguir trabajando:

+ + + +

Resolución de problemas eficaz

+ +

No hay una única forma efectiva de resolver todos los problemas (y aprender todo) lo relacionado con el diseño y desarrollo web, pero hay algunos consejos generales que te servirán en la mayoría de los casos.

+ +

Romper las cosas en trozos

+ +

Para empezar, cuando intentas implementar algo específico y parece realmente difícil entenderlo, debes tratar de dividirlo en múltiples problemas o fragmentos más pequeños.

+ +

Por ejemplo, si estás considerando la tarea de "Crear un sitio web simple de dos columnas", la puedes desglosar de la siguiente manera:

+ + + +

Luego, podrías desglosarlo aún más, por ejemplo, "Implementar menú de navegación horizontal" podría escribirse como:

+ + + +

Cada uno de estos problemas no parece tan difícil de resolver como el gran problema que tuviste inicialmente. ¡Ahora solo tienes que empezar a resolverlos todos!

+ +

Aprende y reconoce los patrones

+ +

Como dijimos antes, el diseño/programación web se trata principalmente de resolución de problemas y patrones. Una vez que hayas escrito lo que necesitarás hacer para resolver un problema específico, puedes comenzar a descubrir qué características tecnológicas usar para resolverlo. Por ejemplo, los desarrolladores web profesionales han creado muchos menús de navegación horizontal, por lo que inmediatamente comenzarás a pensar en una solución como esta:

+ +

Un menú de navegación generalmente se crea a partir de una lista de enlaces, algo así como:

+ +
<ul>
+  <li>Primer elemento del menú</li>
+  <li>Segundo elemento del menú</li>
+  <li>Tercer elemento del menú</li>
+  <li>etc.</li>
+</ul>
+
+ +

Para hacer que todos los elementos se asienten horizontalmente en una línea, la forma moderna más fácil es usar flexbox:

+ +
ul {
+  display: flex;
+}
+ +

Para eliminar el espacio innecesario y las viñetas, podemos hacer esto:

+ +
ul {
+  list-style-type: none;
+  padding: 0;
+}
+ +

etc.

+ +

Si realmente eres un principiante en el desarrollo web, tendrás que estudiar y buscar en la web y encontrar soluciones para tales problemas. Si eres un desarrollador web profesional, probablemente recordarás la última vez que resolviste un problema similar, y solo tendrás que buscar algunos bits de la sintaxis que olvidaste desde entonces.

+ +

Cuando encuentres soluciones a tales problemas, vale la pena escribir notas sobre lo que hiciste y mantener algunos ejemplos de código mínimos en un directorio en algún lugar para que puedas mirar hacia atrás en el trabajo anterior.

+ +

Además, la web tiene {{web.link("/es/docs/Learn/Common_questions/What_are_browser_developer_tools", "herramientas de desarrollo")}} que te permiten ver el código utilizado para crear cualquier sitio en la web, si no tienes una solución a mano, un buen método de investigación es encontrar sitios web con características similares en la naturaleza y averiguar cómo lo hicieron.

+ +
+

Nota: Observa cómo hablamos antes sobre el problema que estamos tratando de resolver primero, y la tecnología utilizada para resolverlo, en segundo lugar. Esta, casi siempre es la mejor manera de hacerlo — no comiences con una tecnología nueva y genial que desees usar, e intenta adaptarla a tu caso de uso.

+
+ +
+

Nota: La solución más sencilla suele ser la mejor.

+
+ +

Practica

+ +

Cuanto más practiques la resolución de un problema, más fuertes serán las vías neuronales de tu cerebro en esa área y más fácil será recordar los detalles y la lógica de ese problema en particular.

+ +

Sigue jugando con el código y practica más. Si se te acaban los problemas por resolver, busca algunas pruebas en línea, realiza algunos cursos más o pregunta a tus amigos y familiares (o escuela, o iglesia local) si hay algo que les gustaría que construyeras para ellos.

+ +

Obtener ayuda

+ +

El desarrollo web requiere que aprendas un complejo conjunto de habilidades — a veces estarás atascado y necesitarás ayuda. Como dijimos antes, incluso los desarrolladores profesionales regularmente necesitan ayuda para resolver problemas.

+ +

Hay una variedad de formas de obtener ayuda, y la siguiente información son algunos consejos para hacerlo de manera más efectiva.

+ +

Búsquedas web efectivas

+ +

Una habilidad importante para aprender es el arte de las búsquedas web efectivas — ¿qué términos de búsqueda necesitas usar en tu motor de búsqueda favorito para encontrar los artículos que necesitas?

+ +

A menudo es bastante obvio qué buscar. Por ejemplo:

+ + + +

Si deseas buscar algo que tenga palabras de moda menos obvias, debes pensar en qué es más probable que te devuelva lo que deseas.

+ + + +

Mensajes de error

+ +

Si tienes un problema con algún código y aparece un mensaje de error específico, a menudo es una buena idea copiar el mensaje de error en tu motor de búsqueda y utilizarlo como término de búsqueda. Si otras personas han tenido el mismo problema, es probable que haya algunos artículos o publicaciones de blog al respecto en lugares como MDN o Stack Overflow.

+ +
+

Nota: Stack Overflow es un sitio web realmente útil; básicamente es una enorme base de datos de preguntas y respuestas seleccionadas sobre diversas tecnologías y técnicas relacionadas. Probablemente encontrarás una respuesta que responda a tu pregunta. Si no, puedes hacer una pregunta y ver si alguien puede ayudarte.

+
+ +

Prueba en el navegador

+ +

A menudo es una buena idea ver si tu problema está afectando a todos los navegadores, o si solo ocurre en uno o en un pequeño número de navegadores. Si solo afecta a un navegador, por ejemplo, puedes usar ese navegador para limitar la búsqueda. Las búsquedas de ejemplo podrían verse así:

+ + + +

Usa MDN

+ +

El sitio en el que ya estás tiene una gran cantidad de información disponible, tanto material de referencia para buscar la sintaxis del código como guías/tutoriales para aprender técnicas.

+ +

Hemos proporcionado la mayoría de las respuestas a las preguntas que tendrás sobre los fundamentos del desarrollo web en esta parte de MDN. Si estás atascado, es bueno volver a leer los artículos asociados para ver si te perdiste algo.

+ +

Si no estás seguro de qué artículo leer, intenta buscar en MDN algunas palabras clave relacionadas (como se indicó anteriormente), o intenta una búsqueda web general. Para buscar en MDN, puedes usar la funcionalidad de búsqueda incorporada del sitio o mejor aún, usar tu motor de búsqueda favorito y poner "mdn" delante del término de búsqueda, por ejemplo, "diseño web receptivo mdn" o "backgrounf-color mdn".

+ +

Otros recursos en línea

+ +

Ya mencionamos Stack Overflow, pero hay otros recursos en línea que pueden ayudar.

+ +

Es bueno encontrar una comunidad de la que formar parte, y obtendrás mucho respeto si intentas ayudar a otros a responder sus preguntas y también a hacer las tuyas. Otros buenos ejemplos incluyen:

+ + + +

Sin embargo, también tiene sentido encontrar grupos útiles en sitios de redes sociales como Twitter o Facebook. Busca grupos que discutan los temas de desarrollo web que te interesen y únete. Sigue a las personas en Twitter que sabes que son influyentes, inteligentes o simplemente parecen compartir muchos consejos útiles.

+ +

Encuentros físicos

+ +

Por último, deberías intentar asistir a algunas reuniones físicas para conocer a otras personas de ideas afines, especialmente aquellas que atienden a principiantes. meetup.com es un buen lugar para encontrar reuniones físicas locales, y también puedes probar tu prensa local o lo que hay en los sitios.

+ +

También puedes intentar asistir a conferencias web completas. Si bien estas pueden ser costosas, puedes intentar ofrecerte como voluntario con ellos, y muchas conferencias ofrecen boletos de tarifa reducida, por ejemplo, boletos de estudiante o diversidad.

+ +

Ve también

+ + diff --git a/files/es/learn/codificacion-scripting/index.html b/files/es/learn/codificacion-scripting/index.html new file mode 100644 index 0000000000..50c3065d4a --- /dev/null +++ b/files/es/learn/codificacion-scripting/index.html @@ -0,0 +1,10 @@ +--- +title: Codificación-Scripting +slug: Learn/codificacion-scripting +tags: + - Codificación + - Principiante + - Scripting +translation_of: Learn +--- +

REDIRIGE Aprende

diff --git a/files/es/learn/common_questions/cuanto_cuesta/index.html b/files/es/learn/common_questions/cuanto_cuesta/index.html new file mode 100644 index 0000000000..aeffd72c64 --- /dev/null +++ b/files/es/learn/common_questions/cuanto_cuesta/index.html @@ -0,0 +1,162 @@ +--- +title: ¿Cuánto cuesta hacer algo en la Web? +slug: Learn/Common_questions/Cuanto_cuesta +tags: + - Comenzando + - Herramientas de desarrollo web + - Principiante + - alojamiento + - costo + - hosting +translation_of: Learn/Common_questions/How_much_does_it_cost +--- +
+

Dedicarse a la web no es tan barato como parece. En este artículo discutimos cuánto puedes tener que gastar, y por qué.

+
+ + + + + + + + + + + + +
Prerrequisitos:Deberías ya entender qué software necesitas, la diferencia entre una página web, un sitio web, etc., y qué es un nombre de dominio.
Objetivo:Examina el proceso completo para crear un sitio web y descubre cuánto te puede costar cada paso.
+ +

Resumen

+ +

Al lanzar un sitio web, puedes no gastar nada, o puede que el costo sea muy elevado. En este artículo discutimos acerca de cuánto cuesta todo y cómo obtienes lo que pagas (o no pagas).

+ +

Software

+ +

Editores de texto

+ +

Probablemente tienes un editor de texto: tal como Notepad en Windows, Gedit en Linux, TextEdit en Mac. Le resultará más fácil escribir código si elige un editor que coloree el código, chequee la sintaxis y te ayude a mantener la estructura del programa. 

+ +

Muchos editores son gratis, por ejemplo Atom, BracketsBluefish, TextWrangler, Eclipse, y Netbeans. Algunos, como Sublime Text, los puedes probar tanto como quieras, pero se te anima a pagar. Otros, como PhpStorm, pueden costar entre unas pocas docenas y 200 dólares, en dependencia del plan que pague. Algunos de ellos, como Microsoft Visual Studio, pueden costar cientos o miles de dólares; aunque Visual Studio Express is gratis para desarrolladores individuales o proyectos de código abierto. A menudo, los editores pagados tienen una versión de prueba.

+ +

Para comenzar, le segerimos probar con diferentes editores, para tener un indicio de cuál trabaja mejor para ti. Si está solamente escribiendo código simple de {{Glossary("HTML")}}, {{Glossary("CSS")}}, and {{Glossary("Javascript")}}, utilice un editor sencillo.

+ +

El el precio no refleja de manera confiable la calidad o utilidad de un editor de texto. Tienes que probarlo por ti mismo y decidir si se ajusta a tus necesidades. Por ejemplo, Sublime Text es barato, pero tiene muhos plugins gratis que pueden extender su funcionalidad. 

+ +

Editores de imágenes

+ +

Tu sistema incluye seguramente un simple editor de imágenes, o visor: Paint en Windows, Eye of Gnome en Ubuntu, Preview en Mac. Estos programas son relativamente limitados, pronto gustarás tener un editor más potente para añadir capas, efectos y agrupamiento de imágenes.

+ +

Los editores pueden ser gratis (GIMP, Paint.NET), de costo moderado (PaintShop Pro, menos de $100), o cientos de dólares (Adobe Photoshop).

+ +

Puedes usar cualquiera de ellos, ya que tienen funciones similares, aunque algunos son tan completos que nunca vas a utilizar cada característica. Si en algún punto necesitas intercambiar proyectos con otros diseñadores, deberías descubrir qué herramientas utilizan. Los editores pueden exportar los proyectos finalizados a formatos de archivo estándares, pero cada editor guarda los proyectos actuales en su formato especializado. La mayoría de las imágenes en Internet están protegidas por los derechos de autor, por lo que es mejor chequear la licencia del aechivo antes de utilizarlo. Sitios como Pixabay proporcionan imágenes bajo la licencia CC0, así que la puedes usar, editar y publicar incluso con modificaciones para uso comercial.

+ +

Editores de medios

+ +

Si desea incluir video o audio en su sitio web, puede incrustar servicios online (por ejemplo YouTube, Vimeo, or Dailymotion), o incluir sus propios videos (ver más abajo los costos de ancho de banda).

+ +

Para archivos de audio, puede encontrar software gratuito(Audacity, Wavosaur), o pagar hasta unos poco cientos de dólares (Sony Sound Forge, Adobe Audition). Sin embargo, el software de edición de vídeo puede ser gratis (PiTiVi, OpenShot for Linux, iMovie for Mac), menos de $100 (Adobe Premiere Elements), o varios cientos de dólares (Adobe Premiere Pro, Avid Media Composer, Final Cut Pro). El software recibido con tu cámara digital puede cubrir todas tus necesidades.

+ +

Herramientas de publicación

+ +

Además necesitas una forma de subir archivos: desde tu disco duro a un servidor web distante. Para hacer esto deberías utilizar una herramienta de publicación tal como un cliente  (S)FTP, RSync, o Git/GitHub.

+ +

Cada sistema operativo incluye un cliente (S)FTP, como parte de su administrador de archivos. Windows Explorer, Nautilus (un administrador de archivos común en Linux), y Mac Finder inclueyen todos esta funcionalidad. Sin embargo, las personas a menudo seleccionan clientes (S)FTP dedicados a mostrar directorios locales y remotos y almacenar contraseñas de servidor.

+ +

Si desea instalar un cliente (S)FTP, existen varias opciones seguras y gratuitas: por ejemplo, FileZilla para todas las plataformas, WinSCP para Windows, Cyberduck para Mac o Windows, y otros más.

+ +

Debido a que el protocolo FTP es inseguro, deberías asegurarte de utilizar SFTP — la versión segura, encriptada de FTP que la mayoría de los sitios de alojamiento (en inglés hosting) actuales ofrecen por defecto— u otra solución segura como Rsync sobre SSH.

+ + + +

Ya debes tener un navegador o puedes conseguirlo gratuito. Si lo necesitas, descarga Firefox aquí o Google Chrome aquí.

+ +

Acceso a la web

+ +

Computadora / módem

+ +

Necesitas una computadora. El costo puede variar mucho, en dependencia de tu presupuesto, y dónde vivas. Para publicar un sitio web básico, sólo necesitas una computadora básica capaz de ejecutar, por lo que el nivel de entrada puede ser bastante bajo. 

+ +

Por supuesto, necesitarás una computadora más formal si quieres producir diseños complicados, retocar fotos, o producir archivos de audio y vídeo. 

+ +

Necesitas subir contenido a un servidor remoto (ver Alojamiento más abajo), por lo que necesitas un módem.Tu proveedor {{Glossary("ISP")}} puede venderte la conexión a internet por unos pocos dólares al mes, aunque tu presupuesto pudiera variar, en dependencia de tu localización.

+ +

Acceso del Proveedor ISP

+ +

Asegúrese de contar con suficiente {{Glossary("Ancho de banda", "ancho de banda")}}:

+ + + +

Alojamiento

+ +

Entendiendo el ancho de banda

+ +

Los proveedores de alojamiento te cobran de acuerdo a cuánto {{Glossary("Ancho de banda", "ancho de banda")}} consume tu sitio web. . Esto depende de cuántas personaas, y robots de rastreo Web, accedan a tu contenido durante un tiempo dado, y cuánto espacio en el servidor tu contenido ocupa. Esta es la razón por la cual las personas usualmente almacenan sus videos en servicios dedicadostales como Youtube, Dailymotion, y Vimeo. Por ejemplo, tu proveedor puede tener un plan que incluye hasta varios miles de visitantes por díam por un uso “razonable”. Sea cuidadoso, puesto que puede variar mucho de un servidor de alojamiento a otro. Como regla de oro, reconozca que el servicio de alojamiento confiable, pagado y personal puede costar alrededor de 10 a 15 dólares al mes. 

+ +
+

Note que que no existe el ancho de banda “ilimitado”. Si consumes una enorme cantidad de ancho de banda, espere pagar una enorme cantidad de dinero.

+
+ +

Nombre de dominio

+ +

Su nombre de dominio tiene que ser comprado a través de un proveedor de nombres (un registrador). Tu proveedor de alojamiento puede además ser un registrador (por ejemplo 1&1 y Gandi  son al mismo tiempo registradores y proveedores de alojamiento). El nombre de dominio usualmente cuesta $5-15 por año. Este costo varía en dependencia de:

+ + + +

Alojamiento de aficionados vs. Alojamiento “empaquetado”

+ +

Cuando deseas publicar un sitio web, puedes hacer todo por ti mismo: preparar una base de datos (si es necesaria), Sistema de Gestión de Contenidos, or {{Glossary("CMS")}} (como Wordpress, Dotclear, spip, etc.), subir tus propias plantillas o contenido preeditado.

+ +

Pudieras utilizar el entorno de tu proveedor de alojamiento, por aproximadamente de 10 a 15 dólares al mes, o suscribirse directamente a un servicio de alojamiento con CMS pre-empaquetado (por ejemplo, Wordpress, Tumblr, Blogger). Para esta última no tienes que pagar nada, pero puedes tener menos control sobre las plantillas y otras opciones. 

+ +

Alojamiento gratuito vs. alojamiento pagado

+ +

Te pudieras preguntar, ¿por qué pago por mi alojamiento cuando existen tantos servicios gratuitos?

+ + + +

Es mejor pagar el alojamiento que depender de alojamiento gratuito, ya que en la mayoría de los sitios pagados es posible trasladar tus archivos fácilmente y el tiempo de actividad está garantizado. La mayoría de los proveedores de alojamiento te dan un gran descuento para comenzar. 

+ +

Algunas personan optan por un enfoque mixto. Por ejemplo, su blog principal en un sitio pagado con un nombre de dominio completo, y a su vez contenido espóntaneo, menos estratégico en un servicio de alojamiento gratuito.

+ +

Agencias y alojamiento de sitios web profesionales

+ +

Si desea un sitio web profesional, probablemente le pedirás a una agencia web que lo haga por ti.
+
+ Aquí, los costos dependen de múltiples factores, tales como: 

+ + + +

...y para alojamiento:

+ + + +

En dependencia de cómo responda estas preguntas, su sitio pudiera costar miles hasta cientos de miles de dólares.

+ +

Próximos pasos

+ +

Ahora que entiende que cantidad de dinero su sitio puede costarle, es tiempo de comenzar a diseñar un sitio web y preparar su entorno de trabajo.

+ + diff --git "a/files/es/learn/common_questions/dise\303\261os_web_comunes/index.html" "b/files/es/learn/common_questions/dise\303\261os_web_comunes/index.html" new file mode 100644 index 0000000000..7e05cbcaad --- /dev/null +++ "b/files/es/learn/common_questions/dise\303\261os_web_comunes/index.html" @@ -0,0 +1,115 @@ +--- +title: ¿Qué contienen los diseños web comunes? +slug: Learn/Common_questions/diseños_web_comunes +tags: + - CSS + - Común + - Diseño + - Diseño Común + - HTML + - Principiante +translation_of: Learn/Common_questions/Common_web_layouts +--- +
{{IncludeSubnav("/en-US/Learn")}}
+ +
+

Cuando diseña páginas para su sitio web es bueno tener una idea de los diseños más comunes.

+
+ + + + + + + + + + + + +
Prerrequisitos:Asegúrese que usted ya ha pensado sobre lo que quiere lograr con su proyecto web.
Objetivo:Aprender dónde colocar las cosas en sus páginas web, y cómo hacerlo. 
+ +

Resumen

+ +

Existe una razón para que hablemos sobre diseño web. Se comienza con una página en blanco, y se pueden tomar muchas direcciones. Si no tienes mucha experiencia, comenzar con una página en blanco pudiera ser un poco temible. Nosotros tenemos alrededor de 25 años de experiencia y te daremos algunas reglas básicas para ayudarte a diseñar tu sitio. 

+ +

Aún ahora con el nuevo enfoque de la web para móviles, la mayoría de las páginas web principales son construídas a partir de las siguientes partes:

+ +
+
Encabezado
+
Visible en la parte superior de cada página de un sitio. Contiene información relevante para todas las páginas (como el nombre del sitio o el logo) y un sistema de navegación fácil de usar.
+
Contenido principal
+
Es el área más grande, contiene contenido único para la página actual.
+
Contenido secundario
+
1) Información complementaria del contenido principal; 2) información compartida entre un subconjunto de páginas; 3) sistema de navegación alternativo. De hecho, todo lo que no es absolutamente requerido por el contenido de la página principal. 
+
Pie de página
+
Visible en la parte inferior de cada página de un sitio. Análogamente al encabezado contiene información global, en este caso menos llamativa como avisos legales o información de contacto.
+
+ +

Estos elementos son bastante comunes en todos los factores de forma, pero pueden ser dispuestos de diferentes maneras. Aquí se presentan algunos ejemplos (1 representa encabezado, 2 pie de página; A contenido principal; B1, B2 barras laterales):

+ +

Diseño de una columna. Especialmente importante para navegadores de móviles de modo que no se llene la pequeña pantalla.

+ +

Example of a 1 column layout: Main on top and asides stacked beneath it.

+ +

Diseño de dos columnas. A menudo utilizado para tabletas, ya que tienen pantallas de tamaño medio.

+ +

 Example of a basic 2 column layout: One aside on the left column, and main on the right column. Example of a basic 2 column layout: One aside on the right column, and main on the left column.

+ +

Diseños de tres columnas. Solamene adecuado para escritorios con pantallas grandes. (Incluso muchos usuarios de escritorio prefieren ver cosas en pequeñas ventanas que en pantalla completa.)

+ +

Example of a basic 3 column layout: Aside on the left and right column, Main on the middle column. Another example of a 3 column layout: Aside side by side on the left, Main on the right column. Another example of a 3 column layout: Aside side by side on the right, Main on the left column.

+ +

La verdadera diversión comienza cuando empiezas a mezclarlos todos juntos.

+ +

Example of mixed layout: Main on top and asides beneath it side by side. Example of a mixed layout: Main on the left column and asides stack on top of each other on the right column Example of a mixed layout: one aside on the left column and main in the right column with a aside beneath main. Example of a mixed layout: Main on the left of the first row and one aside on the right of that same row, a second aside convering the whole second row.

+ +

Estos son solo ejemplos y eres bastante libre de diseñar las cosas como quieras. Puedes notar que mientras el contenido se puede mover alrededor de la pantalla, siempre se mantiene el encabezado (1) en la parte superior y el pie de página (2) en la parte inferior. Además, el contenido principal (A) es lo más importante, así que dale la mayor parte del espacio. 

+ +

Estas son reglas del juego que puedes aprovechar. Desde luego, existen diseños complejos y excepciones. En otros artículos discutiremos cómo diseñar sitios responsivos (sitios que cambian en dependencia del tamaño de la pantalla) y sitios cuyos diseños varían entre las páginas. Por ahora, es mejor mantener tu diseño consistente en todo tu sitio. 

+ +

Aprendizaje activo

+ +

Aún no hay aprendizaje activo disponible. Por favor, considere contribuir.

+ +

Profundización

+ +

Estudiemos algunos ejemplos más concretos tomados de sitios web bien conocidos. 

+ +

Diseño de una columna

+ +

Aplicación de Invision. Un diseño típico de una columna proporcionando toda la información linealmente en una sola página. 

+ +

Example of a 1 column layout in the wild        1 column layout with header, main content, a stack of aside contents and a footer

+ +

Bastante sencillo. Sólo recuerda que muchas personas navegarán por tu sitio desde escritorios, así que haz tu contenido también utilizable allí.

+ +

Diseño de dos columnas.

+ +

Abduzeedo, un simple diseño de blog. Los blogs usualmente tienen dos columnas, una para el contenido principal que es más ancha y otra más estrecha para el contenido secundario (como widgets, niveles de navegación secundarios y anuncios). 

+ +

Example of a 2 column layout for a blog        A 2 column layout with the main content on the left column

+ +

En este ejemplo, mira la imagen (B1) justo debajo del encabezado. Está relacionada con el contenido principal, pero el contenido principal tiene sentido sin esta, de este modo pudieras pensar que la imagen forma parte del contenido principal o del lateral. En realidad no importa. Lo que importa es que si pones algo justo debajo del encabezado, debería ser parte del contenido principal o estar directamente relacionado con este. 

+ +

Es una trampa

+ +

MICA. Este es un poco más complicado. Parece un diseño de tres columnas...

+ +

Example of a false 3 columns layout        It looks like a 3 columns layout but actually, the aside content is floating around.

+ +

...pero no lo es. B1 y B2 flotan alrededor del contenido principal. Recuerda esa palabra "float"--te acordarás cuando empieces a aprender sobre {{Glossary("CSS")}}.

+ +

¿Por qué pensarías que es un diseño de tres columnas? Porque la imagen en la parte superior derecha está en forma de L, porque B1 parece una columna sosteniendo el conenido principal desplazado, y porque la "M" y la  "I" del logo MICA crean una línea de fuerza vertical.

+ +

Este es un buen ejemplo de diseño clásico que admite cierta creatividad. Los diseños simples son más fáciles de implementar, pero deje espacio expresar su creatividad en el área.

+ +

Un diseño mucho más complicado

+ +

La Opera de Paris.

+ +

An example of a tricky layout.        This is a 2 column layout but the header is overlaping the main content.

+ +

Básicamente un diseño de dos columnas, pero notarás muchos ajustes por aquí y por allá que rompen visualmente el diseño. Especialmente, el encabezado se superposiciona a la imagen del contenido principal. La manera en que la curva del menú del encabezado se une con la curva en el fondo de la imagen, hacen que el encabezado y el contenido principal parezcan un solo componente a pesar de que son técnicamente completamente distintos. 

+ +

Como ves, puedes crear maravillosos sitios web incluso sólo con diseños básicos. Échale una mirada a tus propios sitos web favoritos y pregúntate a ti mismo, ¿dónde está el encabezado, el pie de página, el contenido principal y el contenido secundario? Esto te inspirará para tu propio diseño y te dará buenas pistas sobre para cuáles diseños funciona y para cuáles no. 

diff --git a/files/es/learn/common_questions/how_does_the_internet_work/index.html b/files/es/learn/common_questions/how_does_the_internet_work/index.html new file mode 100644 index 0000000000..238ea2e5ae --- /dev/null +++ b/files/es/learn/common_questions/how_does_the_internet_work/index.html @@ -0,0 +1,99 @@ +--- +title: ¿Cómo funciona Internet? +slug: Learn/Common_questions/How_does_the_Internet_work +tags: + - Internet + - Principiante + - Tutorial + - Web +translation_of: Learn/Common_questions/How_does_the_Internet_work +--- +
+

En este artículo se describe lo que es Internet y cómo funciona.

+
+ + + + + + + + + + + + +
Prerequisitos:Ninguno, pero te animamos a leer el Artículo sobre el establecimiento de metas primero.
Objetivo:Aprenderás lo básico de infraestructura técnica de la web y la diferencia entre Internet y Web.
+ +

Resumen

+ +

Internet es la columna vertebral de la Web, la infraestructura técnica que la hace posible. En lo más básico, Internet es una gran red de computadoras que se comunican simultáneamente.

+ +

La historia de internet es algo oscura. Comenzó en la década de 1960 como un proyecto de investigación financiado por el ejercito de los EE.UU, y luego se convirtió en una infraestructura pública en la década de 1980 con el apoyo de muchas universidades públicas y empresas privadas. Las distintas tecnologías que soporta internet han evolucionado con el tiempo, pero la forma en que funciona no ha cambiado mucho: Internet es una forma de conectar las computadoras entre sí y asegurar que, pase lo que pase, encuentren una manera de mantenerse conectadas.

+ +

Aprendizaje activo

+ + + +

Profundizar

+ +

Una simple red

+ +

Cuando dos ordenadores necesitan comunicarse, tienes que vincularlos, ya sea físicamente (por lo general con un cable de Ethernet) o de forma inalámbrica (por ejemplo por WiFi o sistema de Bluetooth). Todos los ordenadores modernos pueden soportar cualquiera de este tipo de conexiones.

+ +
+

Nota: En el resto de este artículo, sólo nos referiremos al uso de cables físicos, pero es igualmente aplicable a las redes inalámbricas.

+
+ +

Dos computadoras conectadas entre sí

+ +

La red no se limita a dos ordenadores, se pueden conectar tantos como se deseen aunque siendo más complicado cada vez. Por ejemplo, para conectar diez ordenadores, se necesitarían 45 cables y unos nueve conectores por ordenador!

+ +

Diez ordenadores interconectados

+ +

Para resolver este problema, cada ordenador en una red está conectado a una pequeña computadora especial llamada enrutador o router (en inglés). Este enrutador cumple una función: tal como hace un señalizador en una estación de tren, el router se encarga de asegurar que el mensaje enviado desde un ordenador emisor llegue al destino correcto. Para que el ordenador B reciba un mensaje desde el ordenador A, este debe enviarlo primero al router, quien a su vez lo remite al ordenador B asegurándose que dicho mensaje no sea entregado a otro ordenador C.

+ +

Una vez que agregamos un enrutador al sistema, nuestra red de 10 ordenadores solo requiere 10 cables: un enchufe para cada ordenador y un enrutador con 10 enchufes.

+ +

Diez ordenadores con un router

+ +

Una red de redes

+ +

Hasta aquí todo es más o menos simple, pero ¿qué sucede al conectar cientos, miles, millones de ordenadores entre sí?. Por supuesto un solo enrutador no puede escalar tanto, pero, si lees cuidadosamente, dijimos que un enrutador es como un pequeño ordenador, entonces ¿qué nos impide conectar dos enrutadores a la vez?. Nada: hagámoslo.

+ +

Dos routers conectados entre sí

+ +

Conectando ordenadores a enrutadores y luego enrutadores entre sí, podemos escalar infinitamente.

+ +

Routers interconectados

+ +

Una red así se acerca mucho a lo que llamamos Internet, pero hay algo que nos falta. Construimos esa red para nuestros propios propósitos. Hay otras redes ahí fuera: tus amigos, tus vecinos, cualquiera puede tener su propia red de ordenadores. Pero no es posible instalar cables entre tu casa y el resto del mundo, así que ¿cómo puedes manejar esto? Bueno, ya hay cables conectados a tu casa, por ejemplo, la energía eléctrica y el teléfono. La infraestructura telefónica ya conecta tu casa con cualquier persona en el mundo, así que es el cable perfecto que necesitamos. Para conectar nuestra red a la infraestructura telefónica, necesitamos un equipo especial llamado modem. Este modem convierte la información de nuestra red en información manejable por la infraestructura telefónica y viceversa.

+ +

Un router conectado a un modem

+ +

Entonces estamos conectados a la infraestructura telefónica. El siguiente paso es enviar el mensaje desde nuestra red a la red que queremos llegar. Para lograr eso, conectaremos nuestra red a un proveedor de servicios de internet (ISP de sus siglas en inglés Internet Service Provider). Un ISP es una empresa que gestiona algunos enrutadores especiales interconectados, que también pueden acceder a enrutadores de otros ISP. Así, el mensaje de nuestra red es llevada a través de la red de redes de ISP, hasta la red de destino. Internet consiste en toda esta infraestructura de redes.

+ +

stack de Internet al completo

+ +

Encontrando ordenadores

+ +

Si deseas enviar un mensaje a una computadora, debes especificar a cuál. Es por ello que todo ordenador conectado a una red cuenta con una dirección única que lo identifica, llamada “dirección IP” o Protocolo de Internet(IP de sus siglas en inglés Internet Protocol). Esta dirección está compuesta por una serie de cuatro números separados por puntos, por ejemplo: 192.168.2.10.

+ +

Para los ordenadores es un identificador simple, pero los humanos tienen mayor dificultad a la hora de recordar y memorizar este tipo de dirección. Con el propósito de convertir esta serie numérica en algo que podamos asociar con mayor facilidad a la dirección IP se utiliza lo que conocemos como nombre de dominio. Por ejemplo, google.com es el nombre de dominio utilizado para sustituir la dirección IP 173.194.121.32. Así, usar un nombre de dominio es la manera más fácil para nosotros de identificar un ordenador a través de Internet.

+ +

Mostrar cómo un nombre de dominio sirve como alias a una dirección IP

+ +

Internet y la web

+ +

Como puedes notar, cuando navegamos por la web con un navegador, normalmente utilizamos el nombre de dominio para llegar a un sitio web. ¿Significa eso que Internet y la Web son la misma cosa? No es tan simple. Como vimos, Internet es una infraestructura técnica que permite que miles de millones de ordenadores estén conectadas entre sí. Algunos de estos ordenadores, llamados servidores web son capaces de enviar mensajes inteligibles a los navegadores. Por tanto Internet es una infraestructura, mientras que la Web es un servicio construido sobre dicha infraestructura. Cabe señalar que existen otros servicios soportados por Internet, como es el correo electrónico e {{Glossary("IRC")}}.

+ +

Próximos pasos

+ + diff --git a/files/es/learn/common_questions/index.html b/files/es/learn/common_questions/index.html new file mode 100644 index 0000000000..4dcdd63447 --- /dev/null +++ b/files/es/learn/common_questions/index.html @@ -0,0 +1,145 @@ +--- +title: Preguntas frecuentes +slug: Learn/Common_questions +tags: + - CodingScripting + - Infrastructure + - Learn + - NeedsTranslation + - TopicStub + - Web + - WebMechanics +translation_of: Learn/Common_questions +--- +
{{LearnSidebar}}
+ +

Esta sección del área de aprendizaje está diseñada para proveer respuestas a preguntas frecuentes que pueden surgir, las cuales no son necesariamente parte del núcleo  estructurado de formas de aprendizaje (ej. los artículos de aprendizaje de HTML o CSS). Éstos artículos están diseñados para trabajar por su cuenta.

+ +

Cómo funciona la Web

+ +

Esta sección cubre los mecanismos de la web -preguntas relativas al conocimiento general del ecosistema de la Web y cómo funciona.

+ +
+
+

¿Cómo funciona la Web?

+
+
Internet es la columna vertebral de la Web, la infraestructura técnica que hace la Web posible. Básicamente, Internet es una gran red de ordenadores que se comunican todos entre sí. Este artículo explica cómo funciona, en un nivel básico.
+
+

¿Cúal es la diferencia entre página web, sitio web, servidor web y motor de búsqueda?

+
+
En este artículo se describen varios conceptos relacionados con la web: páginas web, sitios web, servidores web y motores de búsqueda. Estos términos son confundidos habitualmente por los novatos en la Web, o son incorrectamente usados. ¡ Vamos a aprender que significa cada uno de ellos !
+
+

¿Qué es una URL?

+
+
Con {{Glossary("Hypertext")}} y {{Glossary("HTTP")}}, URL es uno de los conceptos clave de la Web. Es el mecanismo usado por {{Glossary("Browser","browsers")}} para recoger cualquier recurso publicado en la Web.
+
+

¿Qué es un nombre de dominio?

+
+
Los nombres de dominio son una parte clave de la infraestructura de Internet. Éstos proveen direcciones entendibles por humanos para cualquier servidor web disponible en Internet.
+
+

¿Qué es un servidor web?

+
+
El término "servidor Web" puede referirse a hardware o software que sirve sitios web a clientes de la Web - o a ambos trabajando conjuntamente. En este artículo veremos cómo funcionan los servidores web, y por qué son importantes.
+
+

¿Qué son los hipervínculos?

+
+
En este artículo, veremos qué son los hipervínculos y por qué importan.
+
+ +

Herramientas y Organización

+ +

Preguntas relacionadas con las herramientas/software que puedes usar para hacer páginas web.

+ +
+
+

¿Cúanto cuesta hacer algo en la web?

+
+
Cuando tú vas a lanzar un sitio web, no deberías malgastar nada de tus costes. En este artículo explicamos cuánto cuesta todo y qué consigues por lo que estás pagando (o no pagando).
+
+

¿Qué programas necesito para crear un sitio web?

+
+
En este artículo explicamos qué componentes software necesitas para editar, subir o ver un sitio web.
+
+

¿Qué editores hay disponibles?

+
+
En este artículo nos centramos en algunas cosas para reflexionar cuando elegimos e instalamos un editor de texto para el desarrollo web.
+
+ +
+
+

¿Qué son las herramientas de desarrollador del navegador?

+
+
Todos los navegadores proveen un set de herramientas de desarrollo para depurar HTML, CSS y otros códigos web. Este artículo explica cómo usar las funciones básicas de herramientas de desarrollador de tu navegador.
+
+ +
+
+

¿Cómo configuro un ambiente de trabajo básico?

+
+
Cuado trabaje en un proyecto web, querrá probarlo localmente antes de mostrarlo al mundo. Alguno tipos de código requieren un servidor para probarlos, y en este artículo le mostraremos cómo configurar uno. También cubriremos cómo implementar una estructura escalable para que sus archivos se mantengan organizados, incluso cuando su proyecto crezca.
+
+

¿Cómo se asegura de que su sitio web funciona correctamente?

+
+
Así que ha publicado su sitio web en línea, ¡muy bien! ¿Pero estás seguro de que funciona correctamente? Este artículo proporciona algunos pasos básicos para la solución de problemas.
+
+

¿Cómo se configura un servidor local de pruebas?

+
+
+
+

Este artículo explica cómo configurar un servidor local de pruebas simple en su máquina y los conceptos básicos sobre cómo usarlo.

+
+
+
+

¿Cómo subir archivos a un servidor web?

+
+
Este artículo muestra cómo publicar su sitio en línea con herramientas FTP, una de las formas más comunes de obtener un sitio web en línea para que otros puedan acceder a él desde sus computadoras.
+
+

¿Cómo uso las páginas de GitHub?

+
+
Este artículo proporciona una guía básica para publicar contenido utilizando la función gh-pages de GitHub.
+
+

¿Cómo alojar tu sitio web en Google App Engine?

+
+
¿Buscas un lugar donde alojar tu sitio web? Aquí hay una guía paso a paso para alojar tu sitio web en Google App Engine.
+
+

¿Qué herramientas están disponibles para depurar y mejorar el rendimiento del sitio web?

+
+
Este conjunto de artículos le muestra cómo utilizar las herramientas de desarrollo en Firefox para depurar y mejorar el rendimiento de su sitio web, utilizando las herramientas para comprobar el uso de la memoria, el árbol de nodos de JavaScript, la cantidad de nodos que se renderizan en el DOM y más.
+
+ +

Diseño y accesibilidad

+ +

Esta sección enlista preguntas relacionadas con la estética, estructura de páginas, técnicas de accesibilidad, etc.

+ +
+
+

¿Cómo empiezo a diseñar mi sitio web?

+
+
Este artículo cubre el primer paso más importante de cada proyecto: definir lo que desea lograr con él.
+
+

¿Qué contienen los diseños web comunes?

+
+
Al diseñar páginas para su sitio web, es bueno tener una idea de los diseños más comunes. Este artículo recorre algunos diseños web típicos, observando las partes que componen cada uno.
+
+

¿Qué es la accesibilidad?

+
+
Este artículo introduce los conceptos básicos detrás de la accesibilidad web.
+
+

¿Cómo podemos diseñar para todo tipo de usuarios?

+
+
Este artículo proporciona técnicas básicas para ayudarlo a diseñar sitios web para todo tipo de usuario —la accesibilidad rápida gana y otras cosas.
+
+

¿Qué características HTML promueven la accesibilidad?

+
+
Este artículo describe características específicas de HTML que pueden ser utilizadas para hacer una página web más accesible para personas con diferentes discapacidades.
+
+ +

Preguntas de HTML, CSS y JavaScript

+ +

Para soluciones a problemas comunes de HTML/CSS/JavaScript, trata con los siguientes artículos.

+ + diff --git a/files/es/learn/common_questions/pages_sites_servers_and_search_engines/index.html b/files/es/learn/common_questions/pages_sites_servers_and_search_engines/index.html new file mode 100644 index 0000000000..741efd415d --- /dev/null +++ b/files/es/learn/common_questions/pages_sites_servers_and_search_engines/index.html @@ -0,0 +1,119 @@ +--- +title: >- + ¿Cuál es la diferencia entre la página web, el sitio web, el servidor web y el + motor de búsqueda? +slug: Learn/Common_questions/Pages_sites_servers_and_search_engines +translation_of: Learn/Common_questions/Pages_sites_servers_and_search_engines +--- +
+

En este artículo describe varios conceptos referidos a la web: Páginas web, sitios web, servidores web, y motores de búsqueda. Estos términos con frecuencia son confundidos por recién llegados a la web, o son incorrectamente usados. Vamos a aprender que significa de cada uno!

+
+ + + + + + + + + + + + +
Prerrequisitos:Debes saber ¿Cómo funciona internet?.
Objectivo:Aprender la diferencia entre página web, un sitio web, un servidor web, y un motor de búsqueda.
+ +

Resumen

+ +

Así como en cualquier área de conocimiento, la web viene con un montón de jerga. No te preocupes, no te abrumaremos con todo esto (tenemos un glosario por si tienes curiosidad). Sin embargo, hay un unos términos básicos que necesitas entender al principio, Ya que escuchará estas expresiones todo el tiempo mientras lee. A veces es fácil de confundir estos términos, puesto que hacen referencia a funcionalidades relacionadas pero diferentes. De hecho, a veces veras estos términos mal utilizados en las noticias y en otros lugares, por lo que llegar mezclarlos es entendible!

+ +

Cubriremos estos términos y tecnologías con más detalle mientras exploramos más, pero estas definiciones rápidas serán un gran comienzo para ti:

+ +
+
Página web
+
 Un documento que se puede mostrar en un navegador web como Firefox, Google Chrome, Microsoft Internet Explorer o Edge, o Safary de Apple, A menudo también se puede denominar "páginas web" o simplemente "páginas".
+
Sitio web
+
Es una colección de páginas web que se agrupan y normalmente se conectan de varias maneras. A menudo llamado un "sitio web" o simplemente "sitio".
+
Servidor web
+
Una computadora que aloja un sitio web en Internet.
+
Motores de búsqueda
+
Un sitio web que te ayuda a encontrar páginas web, como Google, Bing o Yahoo o DuDuckGo. Normalmente se accede a los motores de búsqueda a través de un navegador web (por ejemplo, puede realizar búsquedas de motores en búsqueda directamente en la barra de direcciones de Firefox, Chrome, etc.) 
+

+ Veamos una analogía simple: una biblioteca pública. Esto es lo que generalmente harías al visitar una biblioteca:
+
+ +
    +
  1. Buscar en un índice de busqueda el título del libro que quiéres.
  2. +
  3. Tomar nota del número de catálogo del libro.
  4. +
  5. Ir a la sección particular que contiene el libro, buscár el número de catálogo del libro y obtener el libro.
  6. +
+ +

Vamos a comparar la biblioteca con un servidor web:

+ + + +
+
+ +

No esta disponible aprendizaje activo aun. Por favor, considere la posibilidad de contribuir.

+ +

Profundizando

+ +

Entonces, vamos a profundizar en cómo estos cuatro términos serán relacionados y por qué a veces se confunden entre sí.

+ +

Página web

+ +

Una página web es un simple documento que puede ser mostrado por un {{Glossary("browser")}}. Estos documentos están escritos en lenguaje {{Glossary("HTML")}} (el que veremos en más detalle en otros artículos). Una página web puede incluir una variedad de diferentes tipos de recursos, tales como:

+ + + +
+

Nota: los buscadores pueden mostrar otros tipos de documentos como archivos {{Glossary("PDF")}} o imágenes, pero el término página webespecíficamente hace referencia a documentos HTML. Por otro lado solo usamos el termino document(documento).

+
+ +

Todas las páginas web disponibles en la red son accesibles mediante una dirección única. Para acceder a una página, simplemente escribe su direcciones en la barra de búsqueda de tu navegador:

+ +

Example of a web page address in the browser address bar

+ +

Un sitio web es una colección de páginas web vinculadas (más sus recursos asociados) que comparten un único nombre de dominio. Cada página web de un sitio web determinado proporciona enlaces explícitos—la mayoría del tiempo en forma de parte del texto que se puede hacer clic—que permite al usuario moverse de una página del sitio a otra.

+ +

Para acceder a un sitio web, escribe su nombre su dominio en la barra de direcciones de tu buscador, y el mostrará la página principal del sitio web, o homepage (casualmente denominada "el home"):

+ +

Example of a web site domain name in the browser address bar

+ +

Página web y sitio web son especialmente fácil de confundir cuando un sitio contiene una única página web Tales sitio son denominados sitios de una sola página.

+ +

Servidor web

+ +

Un servidor web es una computadora que aloja uno o mas sitios web. “Alojar” significa que todas las páginas web y sus archivos soportes están disponibles en esa computadora. El servidor web enviará cualquier página web desde el sitio que hospeda al navegador de cualquier usuario, por cada solicitud del usuario.

+ +

No confundir sito web y servidor web. Por ejemplo, "Mi sitio web no responde", en realidad significa que el servidor web no responde y , por lo tanto, el sitio web no está disponible. Más importante aún, ya que un servidor web puede alojar varios sitios web, el término servidor web nunca se utiliza para designar un sitio, ya que podría causar un gran confusión. En nuestro ejemplo anterior, si dijimos: "Mi servidor web no responde", significa que no hay sitios web en ese servidor web disponibles.

+ +

Buscador

+ +

Los buscadores son una fuente común de confusión en la web. Un buscador es un tipo especial de sitio web que ayuda a los usuarios a encontrar páginas web de sitios web.

+ +

Hay muchos por ahí: Google, Bing, Yandex, DuckDuckGo,y muchos mas. Algunos son genéricos, otros están especializados en ciertos temas. Utilice los que prefiera.

+ +

Muchos principiantes en la web confunden motores de búsqueda con navegadores. Aclaremos esto: Un navegador es una parte de software que devuelve y muestra páginas web; un buscador es un sitio web que ayuda a las personas a encontrar páginas web de otros sitios web. La confusión surge porque, la primera vez que alguien inicia un navegador, el navegador muestra la página principal del motor. Esto tiene sentido, porque, obviamente, lo primero que quieres hacer con un navegador es encontrar una página web para mostrar. No confundas la infraestructura (por ejemplo, el navegador) con el servicio (por ejemplo, el buscador). La distinción te ayudará un poco, pero incluso algunos profesionales hablan imprecisamente, así que no te sientas angustiado por eso.

+ +

Aquí hay una instancia de Firefox que muestra un cuadro de búsqueda de Google como su página de inicio predeterminada:

+ +

Example of Firefox nightly displaying a custom Google page as default

+ +

Próximos pasos

+ + + +

 

diff --git a/files/es/learn/common_questions/que_es_un_servidor_web/index.html b/files/es/learn/common_questions/que_es_un_servidor_web/index.html new file mode 100644 index 0000000000..4969677db6 --- /dev/null +++ b/files/es/learn/common_questions/que_es_un_servidor_web/index.html @@ -0,0 +1,120 @@ +--- +title: Que es un servidor WEB? +slug: Learn/Common_questions/Que_es_un_servidor_WEB +tags: + - Infraestructura + - Principiante + - necesitaEsquema +translation_of: Learn/Common_questions/What_is_a_web_server +--- +
+

En este articulo veremos que son los servidores, cómo funcionan y por qué son importantes.

+
+ + + + + + + + + + + + +
Prerequisitos:Debes saber como funciona internet, y entendiendo la diferencia entre pagina web, sitio web, servidor y motor de busqueda
Objetivo:Aprender qué es un servidor web y comprender cómo funciona.
+ +

Sumario

+ +

Con "Servidor web" podemos referirnos a hardware o software, o a ambos trabajando juntos.

+ +
    +
  1. En cuanto a hardware, un servidor web es una computadora que almacena los archivos que componen un sitio web (ej.  documentos HTML , imágenes, hojas de estilos CSS y archivo JavaScript) y los entrega al dispositivo del usuario final. Está conectado a internet y es accesible a través de un nombre de dominio como mozilla.org.
  2. +
  3. En cuanto a software, un servidor web tiene muchas partes encargadas del control sobre cómo tienen acceso los usuarios a los archivos, por lo menos un servidor HTTP. Un servidor HTTP es una pieza de software que comprende {{Glossary("URL","URLs")}} (direcciones web) y {{Glossary("HTTP")}} (el protocolo que tu navegador usa para ver las páginas web).
  4. +
+ +

Al nivel más básico, siempre que un navegador necesite un archivo almacenado en un  servidor web, el navegador hará una solicitud al servidor mediante la vía HTTP. Cuando la petición llega al servidor web correcto (hardware), el  servidor HTTP  (software) envía el archivo antes solicitado, tambien a través de HTTP.

+ +

Basic representation of a client/server connection through HTTP

+ +

Para publicar un sitio web, necesitarás un servidor web dinámico o estático.

+ +

Un servidor web estático, o pila, consiste en una computadora (hardware) con un servidor HTTP (software). Llamamos a este "estático" debido a que el servidor envía los archivos almacenados "tal cual" a tu navegador.

+ +

Un servidor web dinámico consiste en un servidor web estático con un software extra , lo común es que sea una aplicación servidor y una  base de datos. Llamamos a esto "dinámico" por que la aplicacion servidor actualiza los archivos almacenados en la base de datos antes de enviarlos mediante el servidor HTTP.

+ +

Por ejemplo, para ver la página que ves en tu navegador finalmente, el servidor aplicación puede mostrar el diseño HTML con contenido desde una base de datos. Sitios como MDN o Wikipedia tienen cientos de páginas web, que no son realmente archivos HTML, si no una estrucura HTML asociada a una gigantesca base de datos. Esto hace mas fácil y rápido el mantenimiento y entrega del contenido.

+ +

Aprendizaje activo

+ +

No hay aprendizaje activo disponible. Por favor, considere colaborar.

+ +

Inmersión más profunda

+ +

Para recuperar una página web, como ya dijimos, su navegador envía una solicitud al servidor web, que procede a buscar el archivo solicitado en su propio espacio de almacenamiento. Al encontrar el archivo, el servidor lo lee, lo procesa según sea necesario y lo envía al navegador. Veamos esos pasos con más detalle.

+ +

Alojamiento de archivos (Hosting)

+ +

Un servidor web primero debe almacenar los archivos del sitio web, es decir, todos los documentos HTML y sus medios relacionados, incluidas las imágenes, las hojas de estilo CSS, los archivos JavaScript, las fuentes y videos.

+ +

Técnicamente, puede alojar todos esos archivos en su propia computadora, pero es mucho más conveniente almacenarlos en un servidor web dedicado que:

+ + + +

Por todas estas razones, encontrar un buen proveedor de alojamiento es una parte clave del desarrollo de su sitio web. Investigue a través de los diversos servicios que ofrecen las compañías y elija uno que se ajuste a sus necesidades y a su presupuesto (los servicios van desde los gratuitos hasta los miles de dólares al mes). Puede encontrar mas información en este artículo.

+ +

Una vez que configura una solución de alojamiento web, solo tiene que cargar sus archivos en su servidor web.

+ +

Comunicación a través de HTTP

+ +

En segundo lugar, un servidor web brinda soporte para HTTP (Hypertext Transfer Protocol ó  Protocolo de Transferencia de Hipertexto). Como su nombre lo indica, HTTP especifica cómo transferir hypertext (es decir, documentos web vinculados) entre dos computadoras.

+ +

Un protocolo es un conjunto de reglas para la comunicación entre dos computadoras. HTTP es un protocolo textual, sin estado.

+ +
+
Textual
+
Todos los comandos son de texto plano y legible para ser leído por humanos.
+
Sin estado
+
Ni el servidor ni el cliente recuerdan las comunicaciones anteriores. Por ejemplo, al confiar solo en HTTP, un servidor no puede recordar la contraseña que ingresó ni el paso que está realizando en una transacción. Necesita un servidor de aplicaciones para tareas como esa. (Cubriremos ese tipo de tecnología en otros artículos).
+
+ +

HTTP proporciona reglas claras sobre cómo se comunican un cliente y un servidor. Cubriremos el propio HTTP en un artículo técnico más adelante. Por ahora, sólo sé consciente de estas cosas:

+ + + +

The MDN 404 page as an example of such error page En un servidor web, el servidor HTTP es responsable de procesar y responder las solicitudes entrantes.

+ +
    +
  1. Al recibir una solicitud, un servidor HTTP primero verifica si la URL solicitada coincide con un archivo existente.
  2. +
  3. Si es así, el servidor web envía el contenido del archivo de nuevo al navegador. Si no, un servidor de aplicaciones construye el archivo necesario.
  4. +
  5. Si ninguno de los procesos es posible, el servidor web devuelve un mensaje de error al navegador, generalmente "404 Not Found". ( Ese error es tan común que muchos diseñadores web pasan bastante tiempo diseñando páginas de error 404.)
  6. +
+ +

Contenido Estático vs. Dinámico

+ +

En términos generales, un servidor puede entregar contenido estático o dinámico. "Estático" significa "servido como está". Los sitios web estáticos son los más fáciles de configurar, por lo que le sugerimos que convierta su primer sitio en un sitio estático.

+ +

"Dinámico" significa que el servidor procesa el contenido o incluso lo genera desde una base de datos. Esta solución proporciona más flexibilidad, pero se vuelve más difícil de manejar, lo que hace que sea mucho más complejo desarrollar el sitio web.

+ +

Tomemos por ejemplo la página que estás leyendo en este momento. En el servidor web que lo aloja, hay un servidor de aplicaciones que toma el contenido del artículo de una base de datos, lo formatea, lo coloca dentro de algunas plantillas HTML y le envía los resultados. En este caso, el servidor de aplicaciones se llama Kuma y está desarrollado con Python (utilizando el framework Django). El equipo de Mozilla creó Kuma para las necesidades específicas de MDN, pero hay muchas aplicaciones similares basadas en otras tecnologías.

+ +

Hay tantos servidores de aplicaciones que es resulta difícil sugerir uno en particular. Algunos servidores de aplicaciones se adaptan a categorías específicas de sitios web como blogs, wikis o tiendas electrónicas; otros, llamados CMS (Content Management Systems ó Sistemas de Gestión de Contenidos), son más genéricos. Si está desarrollando un sitio web dinámico, tómese el tiempo para elegir una herramienta que se adapte a sus necesidades. A menos que desee aprender algo de programación de servidores web (¡es un área emocionante!), no necesita crear su propio servidor de aplicaciones.

+ +

Próximos pasos

+ +

Ahora que estás familiarizado con los servidores web, podrías:

+ + diff --git a/files/es/learn/common_questions/que_software_necesito/index.html b/files/es/learn/common_questions/que_software_necesito/index.html new file mode 100644 index 0000000000..92687e7d13 --- /dev/null +++ b/files/es/learn/common_questions/que_software_necesito/index.html @@ -0,0 +1,226 @@ +--- +title: ¿Qué software necesito para construir un sitio web? +slug: Learn/Common_questions/Que_software_necesito +tags: + - Build a website + - Building + - Mecanismos Web + - Principiante + - software +translation_of: Learn/Common_questions/What_software_do_I_need +--- +
+

En este artículo se explican cuales componentes de software necesita para editar, cargar, o visualizar un sitio web. 

+
+ + + + + + + + + + + + +
Prerrequisitos:Deberías conocer acerca de la diferencia entre páginas web, sitios web, servidores web, y moteres de búsqueda.
Objetivo:Aprender qué componentes de software necesita si quiere editar, cargar o visualizar un sitio web.
+ +

Resumen

+ +

Puede descargar la mayoría de los programas que necesita para el desarrollo web de forma gratuita. Proporcionaremos unos enlaces en este artículo. 

+ +

Necesitarás herramientas para:

+ + + +

Casi todos los sistemas operativos incluyen por defecto un editor de texto y un navegador, el cual puedes usar para ver los sitios web. Como resultado, usualmente sólo necesitas adquirir software para la transferencia de archivos a tu servidor web.

+ +

Aprendizaje activo

+ +

No hay aprendizaje activo disponible todavía. Por favor, considere contribuir.

+ +

Profundización

+ +

Creción y edición de páginas web

+ +

Para crear y editar un sitio web, necesita un editor de texto. Editores de texto crean y modifican archivos de texto sin formato.  Otros formatos, como {{Glossary("RTF")}}, te permiten añadirle formato, como negrita y señalado, esos no son adecuados para escribir páginas web. Debe pensar bien qué editor de texto usar, ya que trabajará intensamente con él mientras construye el sitio web.

+ +

Todos los sistemas operativos de escritorio traen un editor de texto básico. Estos editores son muy sencillos, pero les faltan características especiales para codificar páginas web. Si desea algo un poco más elegante, hay muchas herramientas de terceros disponibles. Editores de terceros, a menudo viene con características extra, como coloreado de sintaxis, autocompletado, secciones expandibles y búsqueda de código. A continuación se muestra una lista de algunos editores:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sistema operativoEditor incorporadoEditor de terceros
Windows + + + +
Mac OS + + + +
Linux + + + +
Chrome OS  + +
+ +

Aquí se muestra una captura de pantalla de un editor de texto avanzado:

+ +

Screenshot of Notepad++. 

+ +

Esta es una captura de panalla de un editor de texto online:

+ +

Screenshot of ShiftEdit

+ +

Subir archivos a la Web

+ +

Cuando tu sitio web está listo para visualización pública , tendrás que subir tus páginas web a tu servidor web. Puedes comprar espacio en un servidor de varios proveedores (vea el artículo ¿Cuánto cuesta hacer algo en la web?). Una vez que establezca qué proveedor utilizar, el proveedor le enviará un correo con la información de acceso, usualmente en la forma de una URL SFTP, nombre de usuario, contraseña, y otra información necesaria para conectarte con su servidor. Tenga en cuenta que el protocolo (S)FTP está actualmente algo pasado de moda, mientras otros sistemas de carga de archivos están comenzando a volverse populares como RSync y Git/GitHub.

+ +
+

Note: FTP es inherentemente inseguro. Deberías asegurarte de que tu proveedor de alojamiento permite el uso de una conexión segura, por ejemplo SFTP o RSync sobre SSH.

+
+ +

Subir archivos a un sitio web es un paso muy importante mientras se crea un sitio web, por lo que sete tema se abarca en detalle en un artículo aparte. Por ahora, se presenta una lista de clientes (S)FTP gratuitos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sistema operativo Software FTP 
Windows + + + +
Linux + +
 Mac OS + +
 Chrome OS + +  
+ + + +

Como ya sabe, necesita un navegador para ver los sitios web. Existen docenas  de opciones de navegadores para uso personal, pero cuando usted está desarrollando un sitio web debe probarlo al menos con los navegadores principales siguientes, para estar seguro de que su sitio web funciona para la mayoría de las personas:  

+ + + +

Si su sitio está destinado a un grupo específico (por ejemplo, una plataforma técnica o país), puede que tenga que probar el sitio con navegadores adicionales, como OperaKonqueror, o UC Browser.

+ +

Sin embargo las pruebas se dificultan debido a que algunos navegadores sólo funcionan en determinados sistemas operativos. Apple Safari se ejecuta en iOS y Mac OS, mientras Internet Explorer corre solamente en Windows. Lo mejor es aprovechar los servicios como BrowsershotsBrowserstack. Browsershots proporciona capturas de pantallas de tu sitio web en diferentes navegadores. Browserstack  realmente te otorga acceso remoto a máquinas virtuales de modo que puedes probar tu sitio en los entornos más comunes. De manera alternativa, puedes instalar tu propia máquina virtual, pero se necesita algo de experiencia. ( Si escoge este camino, Microsoft tiene algunas herramientas para desarrolladores incluso una máquina virtual lista para utilizar en modern.ie.)

+ +

Sin falta ejecute algunas pruebas en dispositivos reales, especialmente en dispositivos móviles reales. Simulación de dispositivos móviles es una tecnología nueva, en evolución y menos confiable que la simulación de escritorio. Desde luego, los dispositivos móviles son costosos, por lo que le sugerimos echar un vistazo a la inictiva de Laboratorios de dispositivos abiertos. Puede además compartir dispositivos quiere probar en diferentes plataformas sin gastar mucho.

+ +

Próximos pasos

+ + + +

 

diff --git "a/files/es/learn/common_questions/qu\303\251_es_una_url/index.html" "b/files/es/learn/common_questions/qu\303\251_es_una_url/index.html" new file mode 100644 index 0000000000..ef50be60ad --- /dev/null +++ "b/files/es/learn/common_questions/qu\303\251_es_una_url/index.html" @@ -0,0 +1,152 @@ +--- +title: ¿Qué es una URL? +slug: Learn/Common_questions/Qué_es_una_URL +translation_of: Learn/Common_questions/What_is_a_URL +--- +
+

Este artículo habla sobre las Uniform Resource Locators (URLs), explicando qué son y cómo se estructuran.

+
+ + + + + + + + + + + + +
Prerequisitos:Primero necesitas saber Como funciona Internet, qué es un servidor Weblos conceptos detrás de los enlaces en la web.
Objetivo:Aprenderás lo que es una URL y como funcionan en la Web.
+ +

Resumen

+ +

Junto con el {{Glossary("Hypertext", "Hipertexto")}} y {{Glossary("HTTP")}}, las URL son uno de los conceptos claves de la Web. Es el mecanismo usado por los {{Glossary("Browser","navegadores")}} para obtener cualquier recurso publicadon en la web.

+ +

URL significa Uniform Resource Locator (Localizador de Recursos Uniforme). Una URL no es más que una direccion que es dada a un recurso único en la Web. En teoria, cada URL valida apunta a un único recurso. Dichos recursos pueden ser páginas HTML, documentos CSS, imagenes, etc. En la practica, hay algunas excepciones, siendo la más común una URL apuntando a un recurso que ya no existe o que ha sido movido. Como el recurso representado por la URL y la URL en si son manejadas por el servidor Web, depende del dueño del servidor web manejar ese recurso y su URL asociada adecuadamente.

+ +

Active Learning

+ +

There is no active learning available yet. Please, consider contributing.

+ +

Profundizando

+ +

Conceptos básicos: anatomía de una URL

+ +

Aquí hay algunos ejemplos de URL:

+ +
https://developer.mozilla.org
+https://developer.mozilla.org/en-US/docs/Learn/
+https://developer.mozilla.org/en-US/search?q=URL
+ +

Cualquiera de esas URL se puede escribir en la barra de direcciones de su navegador para indicarle que cargue la página (recurso) asociada.

+ +

Una URL está compuesta de diferentes partes, algunas obligatorias y otras opcionales. Veamos las partes más importantes usando la siguiente URL:

+ +
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
+ +
+
Protocol
+
http es el protocolo. La primera parte de la URL indica qué protocolo debe usar el navegador. Un protocolo es un método establecido para intercambiar o transferir datos alrededor de una red informática. Por lo general, para sitios web es el protocolo HTTP o su versión segura, HTTPS. La Web requiere uno de estos dos, pero los navegadores también saben cómo manejar otros protocolos como mailto: (para abrir un cliente de correo) o ftp: para manejar la transferencia de archivos, así que no se sorprenda si ve tales protocolos.
+
Domaine Name
+
www.example.com es el nombre de dominio. Indica qué servidor web se solicita. Alternativamente, es posible usar directamente un {{Glossary("dirección IP")}}, pero debido a que es menos conveniente, no se usa con frecuencia en la Web.
+
Port
+
:80 es el puerto. Indica la "puerta" técnica utilizada para acceder a los recursos en el servidor web. Por lo general, se omite si el servidor web utiliza los puertos estándar del protocolo HTTP (80 para HTTP y 443 para HTTPS) para otorgar acceso a sus recursos. De lo contrario es obligatorio.
+
Path to the file
+
/path/to/myfile.html es la ruta al recurso en el servidor web. En los primeros días de la Web, una ruta como esta representaba la ubicación de un archivo físico en el servidor web. Hoy en día, es principalmente una abstracción manejada por servidores web sin ninguna realidad física.
+
Parameters
+
?key1=value1&key2=value2 son parámetros adicionales proporcionados al servidor web. Esos parámetros son una lista de pares clave/valor separados con el símbolo &. El servidor web puede usar esos parámetros para hacer cosas adicionales antes de devolver el recurso. Cada servidor web tiene sus propias reglas con respecto a los parámetros, y la única forma confiable de saber si un servidor web específico está manejando parámetros es preguntando al propietario del servidor web.
+
Anchor
+
#SomewhereInTheDocument es un ancla para otra parte del recurso en sí. Un ancla representa una especie de "marcador" dentro del recurso, dando al navegador las instrucciones para mostrar el contenido ubicado en ese lugar "marcado". En un documento HTML, por ejemplo, el navegador se desplazará hasta el punto donde se define el ancla; en un video o documento de audio, el navegador intentará ir a la hora que representa el ancla. Vale la pena señalar que la parte después del #, también conocido como el identificador de fragmento, nunca se envía al servidor con la solicitud.
+
+ +

{{Note('Existen algunas partes extras y reglas extras con respecto a las URL, pero no son relevantes para usuarios habituales o desarrolladores web. No se preocupe por esto, no necesita conocerlos para construir y usar URL completamente funcionales.')}}

+ +

Puede pensar en una URL como una dirección de correo postal normal: el protocolo representa el servicio postal que desea utilizar, el nombre de dominio es la ciudad o el pueblo y el puerto es como el código postal; la ruta representa el edificio donde se debe entregar su correo; los parámetros representan información adicional como el número de apartamento en el edificio; y, finalmente, el ancla representa a la persona real a la que ha dirigido su correo.

+ +

Cómo usar las URL

+ +

Se puede escribir cualquier URL dentro de la barra de direcciones del navegador para acceder al recurso que se encuentra detrás. ¡Pero esto es sólo la punta del iceberg!

+ +

El lenguaje {{Glossary("HTML")}} — que se discutirá más adelante — hace un uso extensivo de las URL:

+ + + +
+

Nota: Al especificar URL para cargar recursos como parte de una página (como cuando se usa <script>, <audio>, <img>, <video> y similares), solo debe usar URL HTTP y HTTPS. El uso de FTP, por ejemplo, no es particularmente seguro y muchos navegadores ya no lo admiten.

+
+ +

Otras tecnologías, como {{Glossary("CSS")}} o {{Glossary("JavaScript")}}, usan URLs ampliamente, y estos son realmente el corazón de la Web.

+ +

URL absolutas vs URL relativas

+ +

Lo que vimos arriba se llama URL absoluta, pero también hay algo llamado URL relativa. Examinemos lo que significa esa distinción con más detalle.

+ +

Las partes requeridas de una URL dependen en gran medida del contexto en el que se utiliza la URL. En la barra de direcciones de su navegador, una URL no tiene ningún contexto, por lo que debe proporcionar una URL completa (o absoluta), como las que vimos anteriormente. No necesita incluir el protocolo (el navegador usa HTTP de manera predeterminada) o el puerto (que solo se requiere cuando el servidor web de destino está utilizando algún puerto inusual), pero todas las otras partes de la URL son necesarias.

+ +

Cuando se usa una URL dentro de un documento, como en una página HTML, las cosas son un poco diferentes. Debido a que el navegador ya tiene la propia URL del documento, puede usar esta información para completar las partes faltantes de cualquier URL disponible dentro de ese documento. Podemos diferenciar entre una URL absoluta y una URL relativa mirando solo la parte de ruta de la URL. Si la parte de ruta de la URL comienza con el carácter "/", el navegador buscará ese recurso desde la raíz superior del servidor, sin referencia al contexto dado por el documento actual.

+ +

Veamos algunos ejemplos para aclarar esto.

+ +

Ejemplos de URL absolutas

+ +
+
URL Completa (la misma que usamos antes)
+
+
https://developer.mozilla.org/en-US/docs/Learn
+
+
Protocolo implícito
+
+
//developer.mozilla.org/en-US/docs/Learn
+ +

En este caso, el navegador llamará a esa URL con el mismo protocolo que el utilizado para cargar el documento que aloja esa URL.

+
+
Nombre de dominio implícito
+
+
/en-US/docs/Learn
+ +

Este es el caso de uso más común para una URL absoluta dentro de un documento HTML. El navegador utilizará el mismo protocolo y el mismo nombre de dominio que el utilizado para cargar el documento que aloja esa URL. Nota: no es posible omitir el nombre de dominio sin omitir también el protocolo.

+
+
+ +

Ejemplos de URL relativas

+ +

Para comprender mejor los siguientes ejemplos, supongamos que las URL se invocan desde el documento ubicado en la siguiente URL:https://developer.mozilla.org/en-US/docs/Learn

+ +
+
Sub-recursos
+
+
Skills/Infrastructure/Understanding_URLs
+
+ Debido a que la URL no se inicia con /, el navegador intentará encontrar el documento en un subdirectorio del que contiene el recurso actual. Entonces, en este ejemplo, realmente queremos llegar a esta URL:https://developer.mozilla.org/en-US/docs/Learn/Skills/Infrastructure/Understanding_URLs
+
Volviendo en el árbol de directorios
+
+
../CSS/display
+ +

En este caso, usamos el ../ convención de escritura, heredada del mundo del sistema de archivos UNIX, para decirle al navegador que queremos subir desde un directorio. Aquí queremos llegar a esta URL:https://developer.mozilla.org/en-US/docs/Learn/../CSS/display, que se puede simplificar a: https://developer.mozilla.org/en-US/docs/CSS/display

+
+
+ +

URL semánticas

+ +

A pesar de su sabor muy técnico, las URL representan un punto de entrada legible para un sitio web. Se pueden memorizar y cualquiera puede ingresarlos en la barra de direcciones de un navegador. Las personas están en el centro de la Web, por lo que se considera una buena práctica construir lo que se llama URL semánticas. Las URL semánticas usan palabras con un significado inherente que cualquier persona puede entender, independientemente de sus conocimientos técnicos.

+ +

La semántica lingüística es, por supuesto, irrelevante para las computadoras. Probablemente has visto URL que parecen mashups de caracteres aleatorios. Pero hay muchas ventajas en la creación de URL legibles por humanos:

+ + + +

Próximos pasos

+ + diff --git a/files/es/learn/common_questions/set_up_a_local_testing_server/index.html b/files/es/learn/common_questions/set_up_a_local_testing_server/index.html new file mode 100644 index 0000000000..e2223d3c8a --- /dev/null +++ b/files/es/learn/common_questions/set_up_a_local_testing_server/index.html @@ -0,0 +1,113 @@ +--- +title: ¿Cómo se configura un servidor de prueba local? +slug: Learn/Common_questions/set_up_a_local_testing_server +tags: + - Expreso + - Flask + - Lado-del-servidor + - Node + - PHP + - Principiante + - Python + - aprende + - django + - lamp + - servidores +translation_of: Learn/Common_questions/set_up_a_local_testing_server +--- +
+

En este artículo explica cómo configurar un servidor de prueba local simple en su equipo y los conceptos básicos de cómo utilizarlo.

+
+ + + + + + + + + + + + +
Prerrequisitos:Primero debes saber cómo funciona internet, y qué es un servidor web.
Objectivo:Aprenderás cómo configurar un servidor de pruebas local
+ +

Archivos locales versus archivos remotos

+ +

En la mayor parte del área de aprendizaje, te decimos que abras tus ejemplos directamente en un navegador — lo que se hace con doble clic en el archivo HTML, o arrastrándolo y soltándolo en una ventana del navegador o eligiendo Archivo > Abrir... y navegando al archivo HTML, etc. Hay muchas maneras de lograr esto.

+ +

Sabes si estás ejecutando el ejemplo desde un archivo local porque la dirección web tendrá archivo:// al principio, seguido de la ruta al archivo en tu disco duro local. Por el contrario, si ves uno de nuestros ejemplos alojados en GitHub (o un ejemplo en algún otro servidor remoto), la dirección web tendrá http:// o https:// al principio, para mostrar que el archivo ha sido recibido a través de HTTP.

+ +

El problema de probar archivos locales

+ +

Algunos ejemplos no se ejecutarán si los abre como archivos locales. Esto puede deberse a una variedad de razones, siendo las más probables:

+ + + +

Ejecutando un servidor HTTP local simple

+ +

Para evitar el problema de las solicitudes asíncronas, necesitamos probar estos ejemplos ejecutándolos a través de un servidor web local. Una de las maneras más fáciles de hacer esto para nuestros propósitos es usar el módulo SimpleHTTPServer de Python.

+ +

Para hacer esto:

+ +
    +
  1. +

    Instalar Python. Si usas Linux o Mac OS X, ya debe estar disponible en tu sistema. Si eres usuario de Windows, puedes conseguir un instalador desde la página principal de Python y seguir las instrucciones para instalarlo:

    + +
      +
    • Vé a python.org
    • +
    • Debajo de la sección de Descarga, haz clic en el link para Python "3.xxx".
    • +
    • En la parte superior de la página, selecciona el instalador ejecutable windows x86 y descárgalo.
    • +
    • Cuando se haya descargado, córrelo.
    • +
    • En la primera página de instalación, asegúrate de marcar el checkbox "Añadir Python 3.xxx a la ruta"
    • +
    • Clic en Instalar, luego clic en Cerrar cuando la instalación ya haya finalizado.
    • +
    +
  2. +
  3. +

    Abre la terminal (windows)/terminal (OS X/Linux). Para chequear que Python está instalado, ingrese el siguiente comando.

    + +
    +

    Nota: La v del ejemplo en mayuscula (V)

    +
    + +
    python -V
    +
  4. +
  5. +

    Esto debe retornar un número de versión. Si esto esta bien, navega al directorio que contiene tu ejemplo, usando el comando cd.

    + +
    # Incluye el nombre del directorio de entrar en él,
    +por ejemplo cd Escritorio
    +
    +# Use dos puntos para regresar un nivel de directorio
    +si es necesario,por ejemplo cd ../
    +
    +
  6. +
  7. +

    Ingresa el comando para iniciar el servidor en ese directorio:

    + +
    # En Mac y Linux
    +python -m SimpleHTTPServer
    +#Windows
    +python -m http.server
    +
  8. +
  9. +

    Por defecto, se ejecutará el contenido del directorio en un servidor web local, en el puerto 8000. puedes ir a este servidor yendo a la URL localhost:8000 en tu navegador web. Aquí verá el contenido del directorio listado - haga clic en el archivo HTML que desea ejecutar.

    +
  10. +
+ +
+

Nota: si ya tienes corriendo algo en el puerto 8000, puedes escoger otro puerto corriendo el siguiente comando de servidor por un número de puerto alternativo, por ejemplo python -m SimpleHTTPServer 7800. Puedes acceder a tu contenido en ellocalhost:7800.

+
+ +

Ejecución de lenguajes del lado del servidor localmente

+ +

El módulo SimpleHTTPServer de Python es útil, pero desconoce como ejecutar el código escrito en lenguajes como PHP o Python. Para resolver eso necesitarás algo más — lo que necesitarás exactamente depende del lenguaje del lado del servidor que estas intentando de ejecutar. Aquí están un par de ejemplos:

+ + diff --git a/files/es/learn/common_questions/thinking_before_coding/index.html b/files/es/learn/common_questions/thinking_before_coding/index.html new file mode 100644 index 0000000000..f675eb8d80 --- /dev/null +++ b/files/es/learn/common_questions/thinking_before_coding/index.html @@ -0,0 +1,177 @@ +--- +title: ¿Cómo empiezo a diseñar mi sitio web? +slug: Learn/Common_questions/Thinking_before_coding +tags: + - Pensar + - Principiante + - antes de codificar + - ideación + - proyecto +translation_of: Learn/Common_questions/Thinking_before_coding +--- +

Este artículo cubre el primer paso importante de cada proyecto: definir lo que se desea lograr con él.

+ + + + + + + + + + + + +
Prerrequisitos:Ninguno
Objectivo:Aprender a definir metas para darle dirección a tu proyecto web.
+ +

Resumen

+ +

Al comenzar con un proyecto web, muchas personas se enfocan en el aspecto técnico. Por supuesto, debes estar más familiarizado con la técnica de su oficio, pero lo que realmente importa es lo que quieres lograr. Sí, parece obvio, pero demasiados proyectos fallan, no por falta de conocimiento técnico sino por falta de objetivos y visión.

+ +

Entonces cuando tienes una idea y quieres convertirla en un sitio web, hay un par de cuestiones que debes responder antes que alguna otra cosa:

+ + + +

Todo esto es llamado idealización del proyecto y es un primer paso necesario para alcanzar tus metas, si eres un desarrollador principiante o experimentado.

+ +

Aprendizaje Activo

+ +

No hay aprendizaje activo todavía. Por favor, considere la posibilidad de contribuir.

+ +

Profundizando

+ +

Un proyecto nunca comienza por el lado técnico. Los músicos jamás compondrán ninguna música a menos que primero tengan la idea de lo quieren tocar, y eso también vale para los pintores, escritores y desarrolladores web. La técnica viene en segundo lugar.

+ +

La técnica es crítica. Los músicos deben dominar su instrumento, pero los buenos músicos nunca producen buena música sin una idea. Por lo tanto, antes de saltar al lado técnico, por ejemplo código y herramientas, primero debes dar un paso atrás y decidir en detalle lo que deseas hacer.

+ +

Una discusión de horas con los amigos es un buen comienzo, pero inapropiado. Debes sentarte y estructurar tus ideas, para tener una visión clara sobre el camino que debes tomar para materializar tus ideas. Para hacer esto, sólo necesitas lápiz y papel y un tiempo para resolver al menos las siguientes preguntas.

+ +
+

Nota: Hay innumerables maneras de llevar a cabo la ideación del proyecto. No podemos presentarlas a todas aquí (un libro entero no sería suficiente). Lo que presentamos aquí es un método sencillo para manejar lo que los profesionales llaman Ideación de Proyectos, Planificación de Proyectos y Gestión de Proyectos.

+
+ +

¿Qué es exactamente lo que quiero lograr?

+ +

Esta es la más importante pregunta a responder, ya que impulsa todo lo demás. Enumera todas la metas que deseas alcanzar. Puede ser cualquier cosa: vender bienes para ganar dinero, expresar opiniones políticas, conocer nuevos amigos, actuar con músicos, coleccionar imágenes de gatos o lo que quieras.

+ +

Supongamos que eres músico. Y puedes desear que:

+ + + +

Una vez que tengas la lista, necesitas priorizar. Ordena los objetivos desde los más importantes hacia los menos importantes.

+ +
    +
  1. Encontrar un/a nuevo/a novio/a.
  2. +
  3. Permitir que las gente escuche tu música.
  4. +
  5. Hablar acerca de tu música.
  6. +
  7. Conocer otros músicos.
  8. +
  9. Venta de golosinas.
  10. +
  11. Enseñar música a través de vídeos.
  12. +
  13. Publicar fotos de tus gatos.
  14. +
+ +

Haciendo este sencillo ejercicio, escribir metas y clasificarlas, te ayudará cuando tengas que tomar decisiones. (¿Debería implementar estas características, usar estos servicios, crear este diseño?)

+ +

Entonces, ahora que tienes tu lista de objetivos priorizada, pasemos a la siguiente pregunta.

+ +

¿Cómo podría un sitio web llevarme a mis objetivos?

+ +

Entonces, tienes tu lista de objetivos y sientes que necesitas un sitio web para alcanzarlos. ¿Estás seguro?

+ +

Echemos un vistazo a nuestro ejemplo. Tenemos cinco metas relacionadas con la música, una relacionada a la vida personal (Encontrar pareja), y las fotos del gato completamente ajenas. ¿Es razonable construir un único sitio para cubrir todos esos objetivos? ¿Es necesario? Después de todo, una gran cantidad de servicios web existentes podría llevarte a tus objetivos sin necesidad de crear uno nuevo.

+ +

Encontrar pareja es un caso prioritario en el que tiene más sentido utilizar los recursos existentes en lugar de construir todo un nuevo sitio. ¿Por qué? Porque invertiríamos más tiempo construyendo y manteniendo el sitio web en lugar de realmente buscar una pareja. Dado que nuestro objetivo es lo que más importa, debemos gastar nuestra energía en aprovechar las herramientas ya existentes en lugar de empezar desde cero. Una vez más, hay tantos servicios web ya disponibles para mostrar fotos que no vale la pena el esfuerzo para construir un nuevo sitio sólo para anunciar acerca de lo lindo que son nuestros gatos.

+ +

Los otros cinco objetivos están todos conectados con la música. Hay, por supuesto, muchos servicios web que podrían manejar estas metas, pero tiene sentido, en este caso, construir un sitio web propio. Tal sitio web es la manera de agregar todo lo que queremos publicar en un solo lugar (bueno para las metas 3, 5 y 6). En resumen, ya que estos objetivos giran en torno al mismo tema, tener todo en un solo lugar nos ayudará a alcanzar nuestras metas y facilitará a nuestros seguidores el conectarse con nosotros.

+ +

¿Cómo puede un sitio web ayudarme a alcanzar mis metas? Al responder a eso, encontrarás la mejor manera de alcanzar dichas metas y te ahorrarás desperdiciar esfuerzo.

+ +

¿Qué hay que hacer, y en qué orden, para alcanzar mis metas?

+ +

Ahora que sabes qué es lo que quieres lograr, es momento de volver los objetivos en pasos prácticos. Como una nota lateral, tus metas no están necesariamente petrificadas, ellas evolucionan con el tiempo incluso en el transcurso del proyecto, si te encuentras con obstáculos inesperados o simplemente cambias de opinión.

+ +

En lugar de una extensa explicación, volvamos a nuestro ejemplo con esta tabla.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MetasCosas por hacer
Permitir que las gente escuche tu música +
    +
  1. Grabar música
  2. +
  3. Prepara algunos archivos de audio utilizables online (¿Podrías hacer esto con servicios web existentes?)
  4. +
  5. Dale a las personas acceso a tu música en alguna parte de tu sitio web
  6. +
+
Hablar acerca de tu música +
    +
  1. Escribe algunos artículos para iniciar la discusión
  2. +
  3. Define cómo deben lucir los artículos
  4. +
  5. Publica los artículos en el sitio web (¿Cómo hacer esto?)
  6. +
+
Conocer otros músicos +
    +
  1. Provee modos para que las personas te contacten (¿Email? ¿Facebook? ¿Teléfono? ¿Correo?)
  2. +
  3. Define cómo las personas encontrarán esos canales de contacto desde tu sitio web
  4. +
+
Venta de golosinas +
    +
  1. Crea las golosinas
  2. +
  3. Almacena las golosinas
  4. +
  5. Encuentra un modo de manejar el envío
  6. +
  7. Encuentra una manera de manejar el pago
  8. +
  9. Hacer un mecanismo en tu sitio para que la gente haga pedidos
  10. +
+
Enseñar música mediante vídeos +
    +
  1. Grabar vídeos de lecciones
  2. +
  3. Preparara archivos de vídeos visibles online (Una vez más, ¿Podría hacer esto con los servicios de web ya existentes?)
  4. +
  5. Dar a la gente acceso a tus vídeos en alguna parte de tu sitio
  6. +
+
+ +

Dos cosas para resaltar. En primer lugar, algunos de estos items no están relacionados con la web (ej.: Grabar, escribir artículos). A menudo estas actividades fuera de línea importan incluso mucho más que el proyecto del sitio web. En ventas, por ejemplo, es mucho más importante y requiere mucho tiempo manejar la oferta, el pago y el envío que construir un sitio web donde las personas puedan realizar pedidos.

+ +

En segundo lugar, establecer pasos procesables conduce a nuevas preguntas que necesitarás contestar. Por lo general, resultan ser más preguntas de lo que pensábamos al principio. (Ej. : ¿debo aprender a hacer todo yo mismo, pedirle a alguien que lo haga por mí, o utilizar servicios de terceros?).

+ +

Conclusión

+ +

Como puedes ver, la idea simple “Quiero hacer un sitio web” genera una larga lista de quehaceres, la cual sólo crece conforme piensas en ella. Pronto puede parecer abrumador, pero no entres en pánico. No es necesario responder todas las preguntas y no necesitas hacer todo lo de tu lista. Lo que importa es tener una visión de lo que deseas y cómo alcanzarlo. Una vez que tengas una visión clara, necesitarás decidir cómo y cuándo hacerlo. Divida grandes tareas en pequeños pasos procesables, y esos pequeños pasos sumarán a grandes logros.

+ +

 

diff --git a/files/es/learn/common_questions/what_are_browser_developer_tools/index.html b/files/es/learn/common_questions/what_are_browser_developer_tools/index.html new file mode 100644 index 0000000000..c08f596c74 --- /dev/null +++ b/files/es/learn/common_questions/what_are_browser_developer_tools/index.html @@ -0,0 +1,248 @@ +--- +title: ¿Cuáles son las herramientas de desarrollo del navegador? +slug: Learn/Common_questions/What_are_browser_developer_tools +tags: + - CSS + - CodingScripting + - HTML + - Herramientas para el desarrollador + - JavaScript + - Navegador + - Novato + - Principiante + - aprende +translation_of: Learn/Common_questions/What_are_browser_developer_tools +--- +
{{IncludeSubnav("/es/Learn")}}
+ +
+

Todos los navegadores web modernos incluyen un potente conjunto de herramientas para desarrolladores. Estas herramientas hacen una variedad de cosas, desde inspeccionar HTML, CSS y JavaScript actualmente cargados, hasta mostrar qué activos ha solicitado la página y cuánto tiempo tardaron en cargarse. Este artículo explica cómo utilizar las funciones básicas de las herramientas de desarrollo de tu navegador.

+
+ +
+

Nota: Antes de ejecutar los siguientes ejemplos, abre el sitio de ejemplo para principiantes que creamos durante la serie de artículos Introducción a la Web. Lo deberías tener abierto mientras sigues los pasos que explicamos a continuación.

+
+ +

Cómo abrir devtools en tu navegador

+ +

Las herramientas para desarrolladores (devtools) viven dentro de tu navegador en una subventana que se ve más o menos así, dependiendo del navegador que estés utilizando:

+ +

Devtools

+ +

¿Cómo la levantas? Existen tres distintas maneras:

+ + + +

Inspector

+ +

El inspector: explorador del DOM y editor CSS

+ +

Las herramientas del desarrollador, generalmente se abren de forma predeterminada en el inspector, parecido a la siguiente captura de pantalla. Esta herramienta muestra cómo se ve el HTML en tu página en tiempo de ejecución, así como qué CSS se aplica a cada elemento de la página. También te permite modificar instantáneamente el HTML y CSS y ver los resultados de tus cambios reflejados en vivo en la ventana del navegador.

+ +

Inspector resaltado

+ +

Si no ves al inspector,

+ + + +

Explorando el DOM con el inspector

+ +

Para empezar, haz clic con el botón derecho (Ctrl+clic) en un elemento HTML en el inspector del DOM y observa el menú contextual. Las opciones disponibles en el menú varían según el navegador, pero en su mayoría, las más importantes son las mismas:

+ +

Inspector del DOM

+ + + +

Intenta editar algo de tu DOM ahora. Haz doble clic en un elemento o haz clic con el botón derecho del mouse y selecciona Editar como HTML en el menú contextual. Puedes realizar los cambios que desees, pero no los puedes guardar.

+ +

Explorar el editor CSS

+ +

De manera predeterminada, el editor CSS muestra las reglas CSS aplicadas al elemento seleccionado actualmente:

+ +

Inspector CSS

+ +

Estas características son especialmente útiles:

+ + + +

Notarás una serie de pestañas en las que se puede hacer clic en la parte superior del Visor CSS:

+ + + +

Conocer más

+ +

Obtén más información sobre el Inspector en diferentes navegadores:

+ + + +

El depurador de JavaScript

+ +

El depurador de JavaScript te permite observar el valor de las variables y establecer puntos de interrupción, lugares en tu código en los que deseas pausar la ejecución e identificar los problemas que impiden que tu código se ejecute correctamente.

+ +

Depurador de Firefox

+ +

Para llegar al depurador:

+ +

Firefox: Selecciona Desarrollador WebDepurador o presiona Ctrl+Mayús+S para abrir el depurador de JavaScript. Si ya estás viendo las herramientas, haz clic en la pestaña Depurador.

+ +

Chrome: Abre las herramientas para desarrolladores y luego selecciona la pestaña Fuentes. (Opera funciona de la misma manera).

+ +

Edge e Internet Explorer 11: presiona F12 y luego Ctrl+3, o si ya estás viendo las herramientas, haz clic en la pestaña Depurador.

+ +

Safari: Abre las herramientas para desarrolladores y luego selecciona la pestaña Depurador.

+ +

Explorando el depurador

+ +

En Firefox hay tres paneles en el depurador de JavaScript.

+ +

Lista de archivos

+ +

El primer panel de la izquierda contiene la lista de archivos asociados con la página que estás depurando. Selecciona el archivo con el que deseas trabajar de esta lista. Haz clic en un archivo para seleccionarlo y ver su contenido en el panel central del depurador.

+ +

Lista de archivos

+ +

Código fuente

+ +

Establece puntos de interrupción donde desees pausar la ejecución. En la siguiente imagen, el resaltado del número 18 muestra que la línea tiene un punto de interrupción establecido.

+ +

Código fuente

+ +

Ver expresiones y puntos de interrupción

+ +

El panel de la derecha muestra una lista de las expresiones en observación que has agregado y los puntos de interrupción que has establecido.

+ +

En la imagen, la primera sección, Ver expresiones, muestra que se ha agregado la variable listItems. Puedes expandir la lista para ver los valores del arreglo.

+ +

La siguiente sección, Puntos de interrupción, enumera los puntos de interrupción establecidos en la página. En example.js, se ha establecido un punto de interrupción en la instrucción listItems.push(inputNewItem.value);

+ +

Las dos últimas secciones solo aparecen cuando el código se está ejecutando.

+ +

La sección Pila de llamadas muestra qué código se ejecutó para llegar a la línea actual. Puedes ver que el código está en la función que maneja un clic del mouse y que el código está actualmente en pausa en el punto de interrupción.

+ +

La sección final, Alcances, muestra qué valores son visibles desde varios puntos dentro de tu código. Por ejemplo, en la siguiente imagen, puedes ver los objetos disponibles para el código en la función addItemClick.

+ +

ver elementos

+ +

Conocer más

+ +

Obtén más información sobre el depurador de JavaScript en diferentes navegadores:

+ + + +

La consola de JavaScript

+ +

La consola de JavaScript es una herramienta increíblemente útil para depurar JavaScript que no funciona como se esperaba. Te permite ejecutar líneas de JavaScript en la página actualmente cargada en el navegador e informa los errores encontrados cuando el navegador intenta ejecutar tu código. Para acceder a la consola en cualquier navegador:

+ +

Si las herramientas para desarrolladores ya están abiertas, haz clic o presiona la pestaña Consola.

+ +

De lo contrario, Firefox te permite abrir la consola directamente usando Ctrl+Mayús+K o usando el comando del menú: Menú ➤ Desarrollador web ➤ Consola web, o Herramientas ➤ Desarrollador web ➤ Consola web. En otro navegador, abre las herramientas para desarrolladores y luego haz clic en la pestaña Consola.

+ +

Esto te dará una ventana como la siguiente:

+ +

Sólo consola

+ +

Para ver qué sucede, intenta ingresar los siguientes fragmentos de código en la consola uno por uno (y luego presiona Intro):

+ +
    +
  1. +
    alert('hello!');
    +
  2. +
  3. +
    document.querySelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    const myWordmark = document.createElement('img');
    +myWordmark.setAttribute('src','https://blog.mozilla.org/press/wp-content/themes/OneMozilla/img/mozilla-wordmark.png');
    +document.querySelector('h1').appendChild(myWordmark);
    +
  6. +
+ +

Ahora intenta ingresar las siguientes versiones incorrectas del código y ve lo que obtienes.

+ +
    +
  1. +
    alert('hello!);
    +
  2. +
  3. +
    document.cheeseSelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    const myWordmark = document.createElement('img');
    +myBanana.setAttribute('src','https://blog.mozilla.org/press/wp-content/themes/OneMozilla/img/mozilla-wordmark.png');
    +document.querySelector('h1').appendChild(myWordmark);
    +
  6. +
+ +

Comenzarás a ver el tipo de errores que devuelve el navegador. A menudo, estos errores son bastante crípticos, ¡pero debería ser bastante sencillo resolver estos problemas!

+ +

Conocer más

+ +

Obtén más información sobre la consola de JavaScript en diferentes navegadores:

+ + + +

Ve también

+ + diff --git a/files/es/learn/common_questions/what_are_hyperlinks/index.html b/files/es/learn/common_questions/what_are_hyperlinks/index.html new file mode 100644 index 0000000000..dd1d28573d --- /dev/null +++ b/files/es/learn/common_questions/what_are_hyperlinks/index.html @@ -0,0 +1,91 @@ +--- +title: Qué son los hipervínculos? +slug: Learn/Common_questions/What_are_hyperlinks +translation_of: Learn/Common_questions/What_are_hyperlinks +--- +
+

En este artículo, repasaremos qué son los hipervínculos y por qué son importantes.

+
+ + + + + + + + + + + + +
Prerrequisitos:Debes saber how the Internet works Y estar familiarizado con the difference between a webpage, a website, a web server, and a search engine.
Objetivo:Conozca los enlaces en la web y por qué son importantes.
+ +

Resumen

+ +

Los hipervínculos, generalmente llamados enlaces, son un concepto fundamental detrás de la Web. Para explicar qué son los enlaces, debemos retroceder a los conceptos básicos de la arquitectura web.

+ +

En 1989, Tim Berners-Lee, el inventor de la Web, habló de los tres pilares en los que se basa la Web:

+ +
    +
  1. {{Glossary("URL")}}, un sistema de direcciones que realiza un seguimiento de los documentos web
  2. +
  3. {{Glossary("HTTP")}}, un protocolo de transferencia para encontrar documentos cuando se les da su URL
  4. +
  5. {{Glossary("HTML")}}, un formato de documento que permite hipervínculos incrustados
  6. +
+ +

Como puede ver en los tres pilares, todo en la Web gira en torno a los documentos y cómo acceder a ellos. El propósito original de la Web era proporcionar una manera fácil de alcanzar, leer y navegar a través de documentos de texto. Desde entonces, la Web ha evolucionado para proporcionar acceso a imágenes, videos y datos binarios, pero estas mejoras apenas han cambiado los tres pilares.

+ +

Antes de la Web, era bastante difícil acceder a los documentos y pasar de uno a otro. Al ser legibles por humanos, las URL ya facilitaron las cosas, pero es difícil escribir una URL larga cada vez que desee acceder a un documento. Aquí es donde los hipervínculos revolucionaron todo. Los enlaces pueden correlacionar cualquier cadena de texto con una URL, de modo que el usuario pueda alcanzar instantáneamente el documento de destino activando el enlace.

+ +

Los enlaces se destacan del texto circundante al estar subrayados y en texto azul. Toque o haga clic en un enlace para activarlo, o si usa un teclado, presione Tab hasta que el enlace esté enfocado y presione Entrar o la barra espaciadora.

+ +

Example of a basic display and effect of a link in a web page

+ +

Los enlaces son el avance que hizo que la Web fuera tan útil y exitosa. En el resto de este artículo, discutimos los diversos tipos de enlaces y su importancia para el diseño web moderno.

+ +

Profundizando

+ +

Como dijimos, un enlace es una cadena de texto vinculada a una URL, y usamos enlaces para permitir saltar fácilmente de un documento a otro. Dicho esto, hay algunos matices que vale la pena considerar:

+ +

Tipos de enlaces

+ +
+
Enlace interno
+
Un enlace entre dos páginas web, donde ambas páginas pertenecen al mismo sitio web, se denomina enlace interno. Sin enlaces internos, no existe un sitio web (a menos, por supuesto, que sea un sitio web de una página).
+
Enlace externo
+
Un enlace desde su página web a la página web de otra persona. Sin enlaces externos, no hay Web, ya que la Web es una red de páginas web. Utilice enlaces externos para proporcionar información además del contenido disponible a través de su página web.
+
Enlaces entrantes
+
Un enlace desde la página web de otra persona a su sitio. Es lo contrario de un enlace externo. Tenga en cuenta que no tiene que volver a vincular cuando alguien vincula a su sitio.
+
+ +

Cuando esté creando un sitio web, concéntrese en los enlaces internos, ya que estos hacen que su sitio sea utilizable. Encuentre un buen equilibrio entre tener demasiados enlaces y muy pocos. Hablaremos sobre el diseño de la navegación del sitio web en otro artículo, pero como regla general, cada vez que agregue una nueva página web, asegúrese de que al menos una de sus otras páginas enlaza con esa nueva página. Por otro lado, si su sitio tiene más de aproximadamente diez páginas, es contraproducente vincular a cada página desde cualquier otra página.

+ +

Cuando comienzas, no tienes que preocuparte tanto por los enlaces externos y entrantes, pero son muy importantes si quieres que los motores de búsqueda encuentren tu sitio (ver más abajo para más detalles).

+ +

Anclas

+ +

La mayoría de los enlaces vinculan dos páginas web. Las anclas unen dos secciones de un documento. Cuando sigue un enlace que apunta a un ancla, su navegador salta a otra parte del documento actual en lugar de cargar un nuevo documento. Sin embargo, crea y utiliza anclajes de la misma manera que otros enlaces.

+ +

Example of a basic display and effect of an anchor in a web page

+ +

Enlaces y motores de búsqueda

+ +

Los enlaces son importantes tanto para los usuarios como para los motores de búsqueda. Cada vez que los motores de búsqueda rastrean una página web, indexan el sitio web siguiendo los enlaces disponibles en la página web. Los motores de búsqueda no solo siguen enlaces para descubrir las distintas páginas del sitio web, sino que también usan el texto visible del enlace para determinar qué consultas de búsqueda son apropiadas para llegar a la página web de destino.

+ +

Los enlaces influyen en la facilidad con que un motor de búsqueda se vinculará a su sitio. El problema es que es difícil medir las actividades de los motores de búsqueda. Las empresas, naturalmente, quieren que sus sitios tengan un alto ranking en los resultados de búsqueda. Sabemos lo siguiente acerca de cómo los motores de búsqueda determinan el rango de un sitio:

+ + + +

SEO (optimización de motores de búsqueda) es el estudio de cómo hacer que los sitios web tengan un alto ranking en los resultados de búsqueda. Mejorar el uso de enlaces de un sitio web es una técnica útil de SEO.

+ +

Próximos pasos

+ +

Ahora querrás configurar algunas páginas web con enlaces.

+ + diff --git a/files/es/learn/common_questions/what_is_a_domain_name/index.html b/files/es/learn/common_questions/what_is_a_domain_name/index.html new file mode 100644 index 0000000000..bc38251b25 --- /dev/null +++ b/files/es/learn/common_questions/what_is_a_domain_name/index.html @@ -0,0 +1,157 @@ +--- +title: ¿Qué es un nombre de dominio? +slug: Learn/Common_questions/What_is_a_domain_name +tags: + - Infraestructura + - Nombres de dominio + - Principiante + - Web +translation_of: Learn/Common_questions/What_is_a_domain_name +--- +
+

En este artículo discutiremos acerca de los nombres de los dominios: qué son, cómo se estructuran y cómo conseguir uno.

+
+ + + + + + + + + + + + +
Prerrequisitos:Primero necesitas saber cómo funciona Internet y entender qué son las URLs.
Objetivo:Aprende qué son los nombres de dominio, cómo funcionan, y por qué son importantes.
+ +

Resumen

+ +

Los nombres de dominio son una parte clave de la infraestructura de internet.  Proporcionan una dirección legible para cualquier servidor web disponible en Internet.

+ +

Cualquier computadora conectada a Internet puede ser alcanzada a partir de una dirección {{Glossary("IP")}} pública, la cual puede estar formada por 32 bits para el protocolo IPv4 (por lo general se escribe con 4 números separados por puntos entre el 0 y 255, por ejemplo, 173.194.121.32) o por 128 bits para la versión IPv6 (formada por 8 grupos de 4 números hexadecimales separados por dos puntos, ejemplo 2027:0da8:8b73:0000:0000:8a2e:0370:1337). Las computadoras pueden manejar estas direcciones fácilmente, pero las personas pasan trabajo para saber de quien es el servidor o que servicio ofrece, ya que un número por sí solo no dice mucho. Además las direcciones IP son difíciles de recordar y pueden cambiarse en cualquier momento. Para resolver estos problemas se usan direcciones que las personas pueden leer, que son intuitivas, fáciles de recordar y dicen mucho sobre el servicio web que ofrecen, se denominan nombres de dominio. 

+ +

Ánalisis del tema

+ +

Estructura de los nombres de dominio

+ +

Un nombre de dominio tiene una estructura simple formada por varias partes (puede tener solamente una parte, dos, tres,...), separadas por puntos y se leen de derecha a izquierda:

+ +

Anatomy of the MDN domain name

+ +

Cada una de estas partes provee información específica sobre el nombre de dominio completo.

+ + + +
+
{{Glossary("TLD")}} (Top-Level Domain) Dominio de primer nivel.
+
El TLD proporciona la información más genérica. Los TLDs les dicen a usuarios el propósito general del servicio que se esconde tras el nombre de dominio. Los TLDs más genéricos (.com, .org, .net) no requieren que los servicios web cumplan ningún criterio particular, pero algunos TLDs hacen cumplir políticas más estrictas por lo que es más claro su propósito. Por ejemplo:
+
Etiqueta (o componente)
+
Las etiquetas son lo que siguen al TLD. Una etiqueta puede se cualquier cosa desde una letra hasta una oración completa. La etiqueta localizada a la derecha antes del TLD puede ser llamada también Dominio de Nivel Secundario, en inglés Secondary Level Domain (SLD). Un nombre de dominio puede tener muchas etiquetas (o componentes), no es obligatorio ni necesario tener tres etiquetas para formar un nombre de dominio. Por ejemplo,    www.inf.ed.ac.uk es un nombre de dominio correcto. Para cualquier dominio sobre el que se tenga control (por ejemplo mozilla.org), uno puede crear otros nombres de dominio (a veces llamados "subdominios", por ejemplo developer.mozilla.org o iot.mozilla.org).
+
+ +

Comprar un nombre de dominio

+ +

¿Quién es propietario de un nombre de dominio?

+ +

No se puede “comprar un nombre de dominio”.  Se paga por el derecho de usar un nombre de dominio por uno o más años. Se pueden renovar los derechos  y la renovación tiene prioridad sobre las aplicaciones de otras personas. Pero nuncá se podrá apropiar se un nombre de dominio. Una vez que deja de pagarlo queda libre para que otras personas puedan utilizarlo.

+ +

Las compañías llamadas registradores utilizan los registros de nombres de dominio para realizar un seguimiento de la información técnica y administrativa que lo conecta con su nombre de dominio.

+ +
+

Nota :  Para algunos nombres de dominio pudiera no ser un registrador quien esté a cargo de mantener el seguimiento. Por ejemplo, cada nombre de dominio bajo .fire es manejado por Amazon.

+
+ +

Encontrar un nombre de dominio disponible

+ +

Para encontrar si un nombre de dominio dado está disponible,

+ + + +
$ whois mozilla.org
+Domain Name:MOZILLA.ORG
+Domain ID: D1409563-LROR
+Creation Date: 1998-01-24T05:00:00Z
+Updated Date: 2013-12-08T01:16:57Z
+Registry Expiry Date: 2015-01-23T05:00:00Z
+Sponsoring Registrar:MarkMonitor Inc. (R37-LROR)
+Sponsoring Registrar IANA ID: 292
+WHOIS Server:
+Referral URL:
+Domain Status: clientDeleteProhibited
+Domain Status: clientTransferProhibited
+Domain Status: clientUpdateProhibited
+Registrant ID:mmr-33684
+Registrant Name:DNS Admin
+Registrant Organization:Mozilla Foundation
+Registrant Street: 650 Castro St Ste 300
+Registrant City:Mountain View
+Registrant State/Province:CA
+Registrant Postal Code:94041
+Registrant Country:US
+Registrant Phone:+1.6509030800
+
+ +

Como se observa, no se puede registrar mozilla.org porque la fundación de Mozilla ya ha sido registrada.

+ +

Por otra parte, veamos si se puede registrar afunkydomainname.org:

+ +
$ whois afunkydomainname.org
+NOT FOUND
+
+ +

Como se observa, el dominio no existe en la base de datos de whois (en el momento que se escribió), por lo que pudiéramos pedir registrarlo. ¡Bueno para saber!

+ +

Obtener un nombre de dominio

+ +

El proceso es bastante sencillo:

+ +
    +
  1. Ir a un sitio de registro.
  2. +
  3. Generalmente hay un letrero que llama la atención que dice “Get a domain name”. Hacer click en él.
  4. +
  5. Rellenar el formulario con todos los detalles requeridos. Asegúrese de no haber escrito incorrectamente el nombre de dominio deseado. ¡Una vez que esté pagado, es muy tarde!.
  6. +
  7. El registrador te permitirá conocer cuando un nombre de dominio esté correctamente registrado. Dentro de unas pocas horas, todos los servidores DNS habrán recibido su información de DNS.
  8. +
+ +
+

Nota: En este proceso se le pide su dirección real. Asegúrese de escribirla correctamente, ya que en algunos países los registradores pueden verse obligados a cerrar el dominio si no pueden proporcionar una dirección válida. 

+
+ +

Actualización de DNS 

+ +

Las bases de datos DNS son almacenadas en cada servidor DNS del mundo, y todos ellos hacen referencia a unos pocos denominados "servidores de nombre autoritario" o "servidores DNS de primer nivel". Cuando su registrador crea o actualiza alguna información para un dominio dado, la información tiene que ser actualizada en cada base de datos DNS. Cada servidor DNS que conoce sobre un dominio dado almacena la información por algún tiempo antes de que sea automáticamente invalidada y luego actualizada ( el servidor DNS consulta un servidor autoritario nuevamente). De esta manera, a los servidores DNS que conocen este nombre de dominio les toma algún tiempo poner la información al día.

+ +
+

Nota : Este tiempo es amenudo llamado tiempo de propagación . Sin embargo, este término no es preciso puesto que la actualizaciónn no se está propagando en sí (primer nivel → nivel inferior). Los servidores DNS consultados por su computadora (nivel inferior) son los que obtienen la información del servidor autoritario(primer nivel) cuando lo necesitan. 

+
+ +

¿Cómo funciona una petición DNS?

+ +

Como ya hemos visto, cuando usted quiere visualizar una página web en su navegador es más simple escribir un nombre de dominio que una dirección IP.  Echemos un vistazo al proceso: 

+ +
    +
  1. Escriba mozilla.org en la barra de direcciones de su navegador.
  2. +
  3. Su navegador le pregunta a su computadora si reconoce la dirección IP identificada por este nombre de dominio (usando una caché DNS local) Si lo hace, el nombre es traducido a la IP y el navegador gestiona el contenido con el servidor web. Fin de la historia.
  4. +
  5. Si la computadora no sabe qué IP está detrás del nombre mozilla.org, hay que pedírselo a un servidor DNS, cuyo trabajo es precisamente decirle a la computadora cuál es la dirección IP de cada nombre de dominio registrado.
  6. +
  7. Ahora que la computadora conoce la dirección IP requerida, su navegador puede gestionar contenidos con el servidor web.
  8. +
+ +

Explanation of the steps needed to obtain the result to a DNS request

+ +

Próximos pasos

+ +

Bien, hemos hablado mucho sobre procesos y arquitectura. Es hora de seguir adelante.

+ + diff --git a/files/es/learn/como_contribuir/index.html b/files/es/learn/como_contribuir/index.html new file mode 100644 index 0000000000..6cc600f24d --- /dev/null +++ b/files/es/learn/como_contribuir/index.html @@ -0,0 +1,88 @@ +--- +title: ¿Cómo contribuir al Área de Aprendizaje en MDN? +slug: Learn/Como_Contribuir +tags: + - Aprender + - Documentación + - Guía + - MDN Meta + - Principiante + - contribuir + - 'l10n:priority' +translation_of: Learn/How_to_contribute +--- +
{{LearnSidebar}}
+ +


+ Si estás aqui, es probable que sea porque estas interesado en contribuir al área de aprendizaje de MDN. ¡Una noticia estupenda!

+ +

En esta página encontrarás todo lo que necesitas para comenzar ayudando a mejorar el contenido de aprendizaje en MDN. Hay muchas cosas que puedes hacer, dependiendo de cuanto tiempo tienes y de si eres principiante, desarrollador web, o profesor.

+ +
+

Nota: Si ya eres colaborador de MDN, no dudes en volver a revisar la página de status de la documentación para mantener un seguimiento del trabajo que se ha realizado y observar cuáles son nuestras prioridades de escritura.

+
+ +
+

Nota: Los colaboradores usan tableros de Trello para organizar sus actividades. Si quieres usarlos, no tienes más que crearte una cuenta de Trello y avisar a Jeremie para que te deje editar el tablero.

+
+ +

Soy principiante

+ +

¡Genial! Los principiantes son muy importantes y valiosos para crear y dar retroalimentación sobre el material de aprendizaje. Tú tienes una perspectiva única sobre estos artículos como miembro de la audiencia a la que están dirigidos, lo cual puede convertirte en un miembro de incalculable valor para nuestro equipo. De hecho, si estás aprendiendo algo de uno de nuestros artículos y te encuentras atascado, o tienes las sensación de que el artículo es algo confuso, puedes modificarlo tú mismo o simplemente informarnos para que podamos resolverlo.

+ +

Colaborar es un gran modo de divertirse mientras se aprenden cosas nuevas. Si alguna vez te sientes perdido o tienes algunas preguntas, no dudes en contactarnos a través de nuestra lista de correo o nuestro canal IRC (ve al final de la página para más detalles).

+ +

A continuación puedes encontrar algunas formas de las que puedes contribuir:

+ +
+
Añade etiquetas a nuestros artículos (5 min)
+
Etiquetar contenido de MDN es una de las formas más sencillas de contribuir a MDN. Como muchas de las características de nuestra plataforma usan etiquetas para ayudar a presentar la información en contexto, la ayuda con el etiquetado es una contribución muy valiosa. Echa un vistazo a la lista de entradas del glosario y a los artículos de aprendizaje sin etiquetas para comenzar.
+
Lee y revisa una entrada de glosario (15 min)
+
Como principiante, necesitamos que tu vista fresca revise nuestro contenido. Si encuentras alguna entrada del glosario difícil de entender, significa que hay que mejorarla. No dudes en realizar cualquier cambio que estimes oportuno. Si crees que no tienes las habilidades adecuadas para editar la entrada, puedes contactarnos a través de nuestra lista de correo.
+
Escribe una nueva entrada de glosario (1 hora)
+
Esta es la forma más eficaz de aprender algo nuevo. Elige un concepto que quieras comprender y, mientras aprendes, escribe una entrada del glosario sobre dicho concepto. Explicar algo a otros es un buen modo de "fijar" el conocimiento a tu cerebro y de ayudarte a darle sentido a las cosas. Todo mientras ayudas a otras personas. ¡Gana todo el mundo!
+
Lee y revisa un artículo de aprendizaje (2 horas)
+
Esto es bastante similar a revisar entradas del glosario (ver arriba); aunque lleva más tiempo, ya que estos artículos son un poco más largos.
+
+ +

Soy desarrollador web

+ +

¡Fantástico! Tus habilidades técnicas son justo lo que necesitamos para asegurarnos de que proporcionamos contenido técnicamente preciso para los principiantes. Como esta parte específica de MDN está dedicada al aprendizaje de la web, asegúrate de explicar las cosas de la forma más sencilla posible. Pero procura no pasarte de sencillez, ya que entonces el contenido deja de ser útil. Es más importante que se comprenda a que sea innecesariamente preciso.

+ +
+
Lee y revisa una entrada de glosario (15 min)
+
Como desarrollador web, te necesitamos para asegurarnos de que nuestro contenido es técnicamente correcto sin ser demasiado pedante. No dudes en realizar cualquier cambio que creas necesario. Si quieres debatir sobre el contenido antes de editarlo, danos un toque a nuestra lista de correo o al canal IRC.
+
Escribe una nueva entrada de glosario (1 hora)
+
Clarificar nuestra jerga técnica es un muy buen modo de aprender y ser técnicamente preciso y simple. La gente con menos experiencia te lo agradecerá. Tenemos muchos términos indefinidos que necesitan tu atención. Escoge uno y listo.
+
Lee y revisa un artículo de aprendizaje (2 horas)
+
Esto es lo mismo que revisar entradas del glosario (ver arriba); aunque lleva un poco más de tiempo, ya que estos artículos son un poco más largos.
+
+ +
+
Escribe un nuevo artículo de aprendizaje (4 horas)
+
En MDN hacen falta artículos sencillos y prácticos sobre el uso de tecnologías web (HTML, CSS, JavaScript, etc). Incluso tenemos contenido viejo en MDN que merece ser revisado y reformado. Lleva tus habilidades al límite para lograr que las tecnologías web puedan ser utilizadas incluso por principiantes.
+
Crea ejercicios, ejemplos de código o herramientas de aprendizaje interactivo (? horas)
+
Todos nuestros artículos de aprendizaje requieren lo que nosotros llamamos materiales de "aprendizaje activo", porque la gente aprende mejor haciendo las cosas por sí mismos. Materiales como ejercicios o contenido interactivo que ayude a los usuarios a aplicar y manejar los conceptos detallados en un artículo. Hay muchas formas de crear contenido de aprendizaje activo, desde crear ejemplos de código con JSFiddle o similares, hasta crear contenido interactivo completamente hackeable con Thimble. ¡Libera tu creatividad!
+
+ +

Soy profesor

+ +

MDN tiene un largo historial de excelencia técnica, pero necesitamos ayuda para mostrar el camino a los principiantes en conceptos técnicos. Aqué es donde entras tú, como profesor o educador. Puedes ayudarnos a asegurar que nuestro material se provee de forma adecuada y práctica para nuestros lectores.

+ +
+
Lee y revisa una entrada en el glosario (15 min)
+
Comprueba una entrada en el glosario y siéntete libre de hacer todos los cambios que creas que son necesarios. Si quieres discutir el contenido antes de editarlo, danos un toque en nuestra lista de correo  or Canal de chat IRC.
+
Escribir una nueva entrada de glosario (1 hora)
+
Las definiciones simples y claras de los términos y las descripciones básicas de los conceptos en el glosario son fundamentales para satisfacer las necesidades de los principiantes. Su experiencia como educador puede ayudar a crear excelentes entradas de glosario; tenemos  muchos terminos indefinidos que necesitan de su atención. Escoge uno y ve por él.
+
Añadir ilustraciones y/o esquemas a los artículos (1 hora)
+
Como ya sabrás, Las ilustraciones son parte invaluable de cualquier contenido de aprendizaje. Esto es algo que generalmente falta en MDN y tus habilidades pueden haer la diferencia en esta área. Mira en los artículos que le falan contenido ilustrativo y escoge uno al que te gustaría crearle los gráficos.
+
Leer y revisar un artículo de aprendizaje (2 horas)
+
Esto es similar a revisar las entradas del glosario (ver arriba), pero requiere más tiempo ya que los artículos son bastante más largos .
+
Escribir un nuevo artículo de aprendizaje (4 horas)
+
Necesitamos artículos simples y directos sobre el ecosistema web y otros temas funcionales a su alrededor. Dado que estos artículos de aprendizaje deben ser educativos en lugar de tratar de cubrir literalmente todo lo que hay que saber, su experiencia en saber qué cubrir y cómo será una gran ventaja.
+
Crear ejercicios, cuestionarios o herramientas interactivas de aprendizaje (? horas)
+
Todos nuestros artículos de aprendizaje requieren lo que llamamos materiales de "aprendizaje activo". Dichos materiales son ejercicios o contenido interactivo que ayudan al usuario a aprender a usar y ampliar los conceptos detallados en un artículo. Aquí puede hacer muchas cosas, desde crear concursos hasta crear contenido interactivo completamente pirateable con  Thimble. Da rienda suelta a tu creatividad!
+
Crea rutas de aprendizaje (? horas)
+
Con el fin de proporcionar tutoriales progresivos y comprensibles, tenemos que dar forma a nuestro contenido en rutas. Es una forma de recopilar contenido existente y descubrir lo que falta para crear un artículo de aprendizaje para escribir .
+
diff --git a/files/es/learn/css/building_blocks/cascada_y_herencia/index.html b/files/es/learn/css/building_blocks/cascada_y_herencia/index.html new file mode 100644 index 0000000000..91a359181f --- /dev/null +++ b/files/es/learn/css/building_blocks/cascada_y_herencia/index.html @@ -0,0 +1,333 @@ +--- +title: Cascada y herencia +slug: Learn/CSS/Building_blocks/Cascada_y_herencia +translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance +--- +
{{LearnSidebar}}{{NextMenu("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks")}}
+ +

El objetivo de este artículo es desarrollar la comprensión de algunos de los conceptos fundamentales de CSS (cascada, especificidad y herencia) que controlan cómo se aplica el CSS al HTML y cómo se resuelven los conflictos.

+ +

A medida que avances en este apartado verás que puede resultar menos relevante y un poco más académico que otros artículos, pero la comprensión de estas cuestiones te ahorrará problemas más adelante. Te animamos a que trabajes meticulosamente este apartado y verifiques que entiendes los conceptos antes de continuar.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y una idea de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Aprender qué son la cascada y la especificidad, y cómo funciona la herencia en CSS.
+ +

Reglas conflictivas

+ +

CSS significa hojas de estilo en cascada (cascading style sheets), y es muy importante entender la palabra cascada. La forma en que se comporta la cascada es la clave para comprender el CSS.

+ +

En algún momento trabajarás en un proyecto y encontrarás que el CSS que pensabas que debería aplicarse a un elemento no funciona. Por lo general, el problema suele ser que has creado dos normas que podrían aplicarse al mismo elemento. La cascada, y el concepto estrechamente relacionado de especificidad son mecanismos que controlan qué regla se aplica cuando aparecen tales conflictos. Es posible que la regla que se apliuca finalmente a tu elemento no sea la que esperas, por lo que debes comprender cómo funcionan estos mecanismos.

+ +

También es significativo el concepto de herencia, que significa que algunas propiedades CSS heredan por defecto los valores establecidos en el elemento padre, pero otras no. Esto también puede causar una respuesta diferente a la que esperas.

+ +

Vamos a empezar por echar un vistazo rápido a los principales elementos que nos interesan, y a continuación veremos cómo interactúan entre sí y con tu CSS. Pueden resultar un poco difíciles de entender, pero a medida que practiques escribiendo CSS te resultará más fácil de entender la manera cómo funcionan.

+ +

Cascada

+ +

En un primer nivel de simplicidad, la cascada en las hojas de estilo significa que el orden de las reglas importa en CSS: cuando dos reglas tienen la misma especificidad, se aplica la que aparece en último lugar en el CSS.

+ +

En el ejemplo siguiente tenemos dos reglas que pueden aplicarse al h1. El h1 acaba siendo de color azul porque estas normas tienen un selector idéntico y, por lo tanto, tienen la misma especificidad. Por esta razón, se aplica la última que aparece.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/cascade-simple.html", '100%', 400)}} 

+ +

Especificidad

+ +

La especificidad es el modo que tiene el navegador de decidir qué regla se aplica si diversas reglas tienen selectores diferentes pero podrían aplicarse a un mismo elemento. Básicamente, la especificidad mide cuán específica es la selección de un selector:

+ + + +

Veamos un ejemplo. Aquí abajo encontrarás dos reglas que pueden aplicarse al elemento h1. Este elemento h1 termina siendo de color rojo: el selector de clase confiere a esta regla una mayor especificidad, así que se aplicará a pesar de la regla para el selector de elemento que aparece más abajo en el orden del código.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/specificity-simple.html", '100%', 500)}} 

+ +

Profundizaremos en la especificidad más adelante.

+ +

Herencia

+ +

La herencia también debe entenderse en este contexto: algunos valores de las propiedades CSS que se han establecido para los elementos padre los heredan los elementos hijo, pero otros no.

+ +

Por ejemplo, si para un elemento se establece el color (color) y el tipo de letra (font-family), cada elemento que se encuentre dentro de él también se mostrará de ese color y con ese tipo de letra, a menos que les se haya aplicado un color y un tipo de letra diferentes directamente.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/inheritance-simple.html", '100%', 550)}} 

+ +

Algunas propiedades no se heredan. Por ejemplo, si para un elemento se establece un ancho {{cssxref("width")}} del 50%, sus descendientes no tendrán un 50% de ancho con respecto al de sus padres. Si este fuera el caso, ¡sería muy frustrante usar CSS!

+ +
+

Nota: En las páginas de referencia de las propiedades CSS de MDN encontrarás un cuadro con información técnica (por lo general, en la parte inferior de la sección de especificaciones) que enumera una serie de puntos sobre cada propiedad, incluyendo cuáles se heredan y cuáles no. Véase, por ejemplo, la sección de especificaciones de la propiedad color.

+
+ +

Comprender cómo trabajan juntos estos conceptos

+ +

Estos tres conceptos controlan qué CSS se aplica a qué elemento. En las secciones siguientes veremos cómo funcionan en conjunto. A veces puede parecer un poco complicado, pero lo irás recordando a medida que ganes experiencia con el CSS, y siempre puedes consultar los detalles si se te olvidan. ¡Incluso los desarrolladores experimentados lo hacen!

+ +

Comprender la herencia

+ +

Vamos a empezar con la herencia. En el ejemplo siguiente tenemos un elemento {{HTMLElement( "ul")}} con dos niveles de listas no ordenadas anidadas en él. Hemos establecido para el <ul> exterior un borde, un relleno y un color de fuente.

+ +

El color se ha aplicado a los hijos directos y también a los hijos indirectos: los elementos hijo <li> inmediatos y los que están dentro de la primera lista. A continuación, hemos añadido a la segunda lista anidada una clase especial y le hemos aplicado un color diferente, que los elementos hijo de esta heredarán.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/inheritance.html", '100%', 700)}} 

+ +

La anchura (como se mencionó anteriormente), los márgenes, el relleno y los bordes no se heredan. Si los elementos hijo de nuestra lista heredaran los bordes, todas las listas y los elementos de lista ganarían un borde cada vez ¡y no es probable que vez quieras un efecto así!

+ +

Las propiedades que se heredan por defecto y las que no son cuestión, en gran medida, de sentido común.

+ +

Control de la herencia

+ +

CSS proporciona cuatro valores de propiedad universales especiales para el control de la herencia. Todas las propiedades CSS aceptan estos valores.

+ +
+
{{cssxref("inherit")}}
+
Establece que el valor de la propiedad que se aplica a un elemento determinado sea exactamente igual al del elemento padre. En la práctica, esto "activa la herencia".
+
{{cssxref("initial")}}
+
Establece que el valor de la propiedad que se aplica a un elemento seleccionado tenga el mismo valor que esté establecido para esa propiedad en la hoja de estilo por defecto del navegador.
+
{{cssxref("unset")}}
+
Restablece la propiedad a su valor natural, lo que significa que si la propiedad se hereda de forma natural, actúa como inherit, y en caso contrario como initial.
+
+ +
+

Nota: También hay un valor más reciente, {{cssxref ("revert")}}, que todavía admiten pocos navegadores.

+
+ +
+

Nota: Véase la sección El origen de las declaraciones CSS en el artículo Introducción al concepto de cascada en CSS para obtener más información sobre cada uno de estos valores y el modo en que funcionan.

+
+ +

A continuación veremos una lista de enlaces y exploraremos cómo funcionan los valores universales. El ejemplo en vivo de abajo te permite jugar con el CSS y ver lo que sucede cuando se hacen cambios. Jugar con el código es la mejor forma de enfrentarse al HTML y el CSS.

+ +

Por ejemplo:

+ +
    +
  1. Se ha aplicado la clase my-class-1 al segundo elemento de lista. Esto establece por herencia el color del elemento <a> que está anidado en él. ¿Cómo cambia el color del enlace si quitamos esta regla?
  2. +
  3. ¿Entiendes por qué el tercer y el cuarto enlace se ven de este color? En caso contrario, comprueba la descripción de los valores anteriores.
  4. +
  5. ¿Cuál de los enlaces va a cambiar de color si se define un nuevo color para el elemento <a>, por ejemplo, a { color: red; }?
  6. +
+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/keywords.html", '100%', 700)}} 

+ +

Restablecer todos los valores de propiedad

+ +

La propiedad CSS abreviada all se puede utilizar para aplicar uno de estos valores de herencia a (casi) todas las propiedades a la vez. Su valor puede ser cualquiera de los valores de herencia (inherit, initial, unset, o revert). Es una forma práctica de deshacer los cambios realizados respecto al estilo para que puedas volver a un punto de partida conocido antes de empezar a introducir cambios.

+ +

En el ejemplo siguiente hay dos bloques de cita. El primero ya tiene un estilo aplicado al propio elemento de cita, mientras que el segundo tiene una clase aplicada al bloque de cita que establece el valor all en unset.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/all.html", '100%', 700)}} 

+ +

Prueba a establecer el valor de all al resto de valores disponibles y observa la diferencia.

+ +

Comprender la cascada

+ +

Ahora entendemos por qué un párrafo que está anidado en la estructura del HTML es del mismo color que el CSS aplicado al cuerpo (body) del HTML y, a partir de los artículos de introducción sabemos cómo cambiar el CSS aplicado a algo en cualquier parte del documento, ya sea mediante la asignación de CSS a un elemento o la creación de una clase. Ahora vamos a echar un vistazo a la forma en que el concepto de cascada define qué reglas CSS se aplican cuando más de un elemento de estilo puede aplicar estilo a un elemento.

+ +

Hay que considerar tres factores, que se enumeran a continuación en orden de importancia creciente. Los posteriores invalidan los anteriores:

+ +
    +
  1. Orden en el código
  2. +
  3. Especificidad
  4. +
  5. Importancia
  6. +
+ +

Vamos a explicarlos para ver cómo los navegadores determinan exactamente que CSS deben aplicar.

+ +

Orden en el código

+ +

Ya hemos visto cómo el orden en el código es importante en el concepto de cascada. Si tienes más de una regla con exactamente el mismo peso, la que ocupa el último lugar en el CSS gana. Puedes entenderlo como que las reglas que están más cerca del elemento considerado sobreescriben las anteriores hasta que la última gana y da formato al elemento.

+ +

Especificidad

+ +

Una vez entendido el hecho de que el orden de los elementos en el código es importante, te encontrarás en alguna situación en la que sabes cuál es la última norma en la hoja de estilo, pero se aplica una regla anterior. Esto se debe a que la regla anterior tiene una especificidad mayor, es decir, es más específica y, por lo tanto, el navegador la escoge como la que debe dar forma al elemento.

+ +

Como hemos visto anteriormente en este mismo artículo, un selector de clase tiene más peso que un selector de elemento, por lo que las propiedades que se definen en la clase tienen prioridad sobre las que se aplican directamente en el elemento.

+ +

Un elemento que hay que tener en cuenta es que aunque pensamos en términos de selectores y reglas que se aplican a lo que estos seleccionan, no es toda la regla lo que se sobrescribe, sino solo las propiedades que entran en conflicto.

+ +

Este comportamiento ayuda a evitar repeticiones en el CSS. Una práctica común es definir estilos genéricos para los elementos básicos y luego, crear clases para los elementos que son diferentes. Por ejemplo, en la hoja de estilo que mostramos a continuación hemos definido estilos genéricos para los encabezados de nivel 2; posteriormente hemos creado algunas clases que solo cambian algunas de las propiedades y los valores. Los valores definidos inicialmente se aplican a todos los encabezados, y entonces los valores más específicos se aplican a los encabezados con las clases.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/mixing-rules.html", '100%', 700)}} 

+ +

Ahora vamos a echar un vistazo a cómo el navegador calcula la especificidad. Ya sabemos que un selector de elemento tiene una especificidad baja y se puede sobrescribir con un elemento de clase. Esencialmente se otorga un valor de puntos a los diferentes tipos de selectores y la suma de estos establece la importancia de ese selector en particular, que a continuación puede evaluarse ante otras posibles coincidencias.

+ +

La cantidad de especificidad de un selector se mide usando cuatro valores diferentes (o componentes), que pueden describirse como millares, centenas, decenas y unidades (cuatro dígitos individuales dispuestos en cuatro columnas):

+ +
    +
  1. Millares: Se suma un punto en esta columna si la declaración está en un atributo de {{htmlattrxref ("style")}} o, como suelen denominarse, estilos en línea. Tales declaraciones no tienen selectores, por lo que su especificidad siempre es 1000.
  2. +
  3. Centenas: Se suma un punto en esta columna por cada selector con ID particular que esté contenido en el selector general.
  4. +
  5. Decenas: Se suma un punto en esta columna por cada selector de clase, de atributo o pseudoclase que estén contenidos en el selector general.
  6. +
  7. Unidades: Se suma un punto en esta columna por cada selector o pseudoelemento que esté contenido en el selector general.
  8. +
+ +
+

Nota: El selector universal (*), los operadores de combinación (+, >, ~, ' ') y la pseudo-clase de negación (:not) no tienen ningún efecto sobre la especificidad.

+
+ +

La tabla siguiente muestra algunos ejemplos concretos para ayudarte a entenderlo mejor. Analízalos y trata de entender por qué tienen la especificidad que les hemos dado. Aun no hemos explicado los selectores de forma detallada, pero puedes encontrar detalles de cada selector en los selectores de referencia de MDN.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorMillares:Centenas:Decenas:Unidades:Especificidad total
h100010001
h1 + p::first-letter00030003
li > a[href*="en-US"] > .inline-warning00220022
#identifier01000100
Sin selector, con una regla en el atributo de un elemento {{htmlattrxref("style")}}10001000
+ +

Antes de continuar, vamos a ver un ejemplo:

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/specificity-boxes.html", '100%', 700)}} 

+ +

¿Qué pasa aquí? En primer lugar, estamos interesados solo en las primeras siete reglas de este ejemplo y, como te habrás dado cuenta, hemos incluido sus valores de especificidad en un comentario antes de cada una.

+ + + +
    +
+ +
+

Nota: Esto solo es un ejemplo aproximado para facilitar la comprensión. En realidad, cada tipo de selector tiene su nivel de especificidad propio, que no pueden sobrescribir los selectores con un nivel de especificidad menor. Por ejemplo, un millar de selectores de clase combinados no serían capaces de sobrescribir las reglas de un selector ID.

+ +

Una forma más precisa de evaluar la especificidad sería anotar los niveles de especificidad individualmente de mayor a menor. Solo cuando hay empate entre las puntuaciones de los selectores dentro de un nivel especifico será necesario evaluar el nivel inferior siguiente; de lo contrario, puedes prescindir de los selectores de especificidad de los niveles inferiores, ya que nunca pueden sobrescribir los niveles de especificidad más altos.

+
+ +

Propiedad !important

+ +

Hay una pieza especial de CSS que se puede utilizar para anular todos los cálculos anteriores, sin embargo se debe tener mucho cuidado con su uso: !important. Se utiliza para convertir una propiedad y un valor particular en el elemento más específico, de modo que se invalidan las reglas normales de la cascada.

+ +

Echa un vistazo a este ejemplo en el que se muestran dos párrafos, uno de los cuales tiene un elemento ID.

+ +

{{EmbedGHLiveSample("css-examples/learn/cascade/important.html", '100%', 700)}} 

+ +

Vamos a observarlo con detenimiento para ver qué sucede. Elimina algunas de las propiedades para ver lo que sucede si te cuesta entender lo que ocurre:

+ +
    +
  1. Verás que se han aplicado los valores de {{cssxref("color")}} y {{cssxref("padding")}} de la tercera regla pero no el de {{cssxref("background-color")}}. ¿Por qué? Deberían haberse aplicado para los tres porque las reglas que se encuentran más adelante en el orden en el código fuente prevalecen sobre las reglas anteriores.
  2. +
  3. Sin embargo, ganan las reglas que están antes porque los selectores de clase tienen mayor especificidad que selectores de elemento.
  4. +
  5. En ambos bloques de código hay una clase {{htmlattrxref("class")}} con el valor better, pero en el segundo bloque de código hay un {{htmlattrxref("id")}} con el valor winning. Puesto que los identificadores tienen una especificidad incluso mayor que las clases (solo puede haber un elemento con un determinado ID en cada página, mientras que puede haber muchos elementos de la misma clase: los selectores ID son muy específicos con lo que delimitan), el primer bloque de código tendría un fondo de color gris y ningún borde, según lo que especifica la clase, mientras que al segundo bloque de código se aplicarían tanto el color de fondo rojo como el borde negro de 1 píxel.
  6. +
  7. El segundo elemento, en cambio, se muestra con el fondo de color rojo pero sin borde. ¿Por qué? Porque la declaración !important que hay en la segunda regla, después de border: none significa que esta declaración tendrá más valor que la regla anterior, aunque el ID de esta tenga mayor especificidad.
  8. +
+ +
+

Nota: La única manera de anular la declaración !important sería incluir otra declaración !important en una declaración con la misma especificidad que aparezca más adelante en el orden del código fuente, o con una especificidad superior.

+
+ +

Es útil saber que !important existe para que sepas qué es cuando te lo encuentres en el código de otras personas. Sin embargo, te recomendamos encarecidamente que no lo utilices a menos que sea absolutamente necesario. !important cambia el modo en que suele funcionar la cascada, por lo que puede dificultar mucho la depuración de problemas en el CSS, especialmente en una hoja de estilo grande.

+ +

Una situación en la que puede que tengas que utilizarlo es si trabajas en un CMS en el que no es posible editar los módulos básicos de CSS y realmente tienes que anular un estilo que no puede anularse de ninguna otra forma. Aun así, te recomendamos encarecidamente que evites su uso.

+ +

El efecto de la ubicación del CSS

+ +

Por último, resulta útil señalar que la importancia de una declaración CSS depende de la hoja de estilo en que se especifica (es posible que los usuarios configuren hojas de estilo personalizadas para anular los estilos de los desarrolladores, por ejemplo, porque el usuario podría tener alguna discapacidad visual, o bien porque desea configurar el tamaño de letra de todas las páginas web que visita para que sea el doble de grande y le proporcione una mayor facilidad de lectura).

+ +

Resumen

+ +

Las declaraciones contradictorias se aplicarán en el orden siguiente (recuerda que las últimas prevalecen sobre las anteriores):

+ +
    +
  1. Declaraciones en las hojas de estilo de agente de usuario (por ejemplo, estilos predeterminados del navegador, que se utilizan cuando no hay otro estilo).
  2. +
  3. Declaraciones normales en las hojas de estilo del usuario (estilos personalizados creados por un usuario).
  4. +
  5. Declaraciones normales en las hojas de estilo de autor (los estilos que creamos nosotros, los desarrolladores web).
  6. +
  7. Declaraciones !important en las hojas de estilo de autor
  8. +
  9. Declaraciones !important en las hojas de estilo del usuario
  10. +
+ +

Para los desarrolladores tiene sentido que sus hojas de estilo anulen a las de usuario para mantener el diseño según lo previsto, pero, como hemos visto, a veces los usuarios tienen buenas razones para anular las directrices de los desarrolladores web. Esto puede lograrse con el uso de !important en sus reglas.

+ +

Pon a prueba tus habilidades

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más importante? Encontrarás más pruebas para verificar que retienes esa einformación en Test your skills: the Cascade.

+ +

¿Qué sigue?

+ +

Si has entendido la mayor parte de este artículo, ¡enhorabuena! Has comenzado a familiarizarte con la mecánica fundamental del CSS. En el artículo siguiente vamos a ver con detalle los selectores.

+ +

Si todavía no tienes una comprensión completa de los conceptos de cascada, especificidad y herencia, ¡no te preocupes! Es, sin duda, lo más complejo que hemos expuesto hasta ahora y es algo que incluso los desarrolladores web profesionales encuentran difícil. Te aconsejamos que regreses a este artículo cuantas veces necesites a medida que avances con el curso.

+ +

Regresa a esta página si empiezas a toparte con problemas extraños o con que los estilos no se aplican de la forma que esperas. Podría ser un problema de especificidad.

+ +

{{NextMenu("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/contenido_desbordado/index.html b/files/es/learn/css/building_blocks/contenido_desbordado/index.html new file mode 100644 index 0000000000..808a519c12 --- /dev/null +++ b/files/es/learn/css/building_blocks/contenido_desbordado/index.html @@ -0,0 +1,123 @@ +--- +title: Contenido desbordado +slug: Learn/CSS/Building_blocks/Contenido_desbordado +translation_of: Learn/CSS/Building_blocks/Overflowing_content +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Handling_different_text_directions", "Learn/CSS/Building_blocks/Values_and_units", "Learn/CSS/Building_blocks")}}
+ +

En este artículo veremos otro concepto importante en CSS: el desbordamiento. El desbordamiento es lo que sucede cuando hay demasiado contenido para que pueda caber cómodamente en una caja. En esta guía aprenderás qué es y cómo administrarlo.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, conocimientos básicos de HTML (véase Introducción al HTML) y nociones de CSS (véase Primeros pasos con el CSS).
Objetivo:Comprender el desbordamiento y cómo gestionarlo.
+ +

¿Qué es el desbordamiento?

+ +

Ya sabemos que todo en CSS está dentro de una caja, y que podemos restringir el tamaño de estas cajas asignándoles los valores {{cssxref ("width")}} y {{cssxref ("height")}} (o {{cssxref("inline-size")}} y {{cssxref("block-size")}}). El desbordamiento es lo que sucede cuando hay demasiado contenido en una caja, y no cabe cómodamente en ella. El CSS te proporciona varias herramientas para administrar este desbordamiento, y además es un concepto que resulta útil de conocer desde las primeras etapas. Te encontrarás con situaciones de desbordamiento con bastante frecuencia al escribir CSS, especialmente cuando profundices en compaginación con CSS.

+ +

El CSS trata de evitar «la pérdida de datos»

+ +

Vamos a comenzar con dos ejemplos que demuestran cómo se comporta el CSS por defecto cuando ocurre un desbordamiento.

+ +

El primero consiste en una caja que a la que se le ha restringido la dimensión al darle una altura. Luego hemos añadido más contenido del que cabe en la caja. El contenido se desborda y se distribuye desordenadamente sobre el párrafo que hay debajo de la caja.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/block-overflow.html", '100%', 600)}}

+ +

El segundo consiste en una palabra dentro de una caja cuya dimensión en línea está restringida. La caja se ha hecho demasiado pequeña para que esa palabra quepa, y se desborda.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/inline-overflow.html", '100%', 500)}}

+ +

Te debes estar preguntando por qué el CSS ha tomado por defecto el enfoque más bien desarreglado de provocar el desbordamiento desordenado del contenido. ¿Por qué no ocultar el contenido adicional o hacer crecer la caja?

+ +

Siempre que sea posible, el CSS no oculta su contenido; hacerlo provocaría la pérdida de datos, que generalmente es un problema. En términos de CSS, esto significa que una parte del contenido desaparece. El problema con que desaparezca contenido es que podría ser que no notaras que ha desaparecido. Tus visitantes podrían no darse cuenta de que ha desaparecido contenido. Si se trata del botón de envío de datos en un formulario, nadie podría completar el formulario, y ¡eso es un gran problema! Así que, en vez de esto, el CSS tiende a desbordarse de un modo que sea visible. Es probable que te des cuenta de ese desarreglo, o en el peor de los casos, que un visitante de tu sitio web te informe de que una parte del contenido se superpone y debas arreglarlo.

+ +

Si has restringido el tamaño de una caja con una anchura o una altura determinadas, el CSS asume que sabes lo que haces y que gestionas correctamente el potencial de desbordamiento. En general, restringir el tamaño de un bloque es problemático cuando el texto se va a poner en una caja, porque puede haber más texto del que te esperabas al diseñar el sitio o el tamaño del texto puede ser mayor, por ejemplo, si el usuario lo aumenta.

+ +

En los artículos siguientes veremos diferentes modos de controlar el tamaño que podrían ser menos propensos a desbordarse. Sin embargo, si necesitas un tamaño fijo, también puedes controlar cómo se comporta el desbordamiento. ¡Sigue leyendo!

+ +

La propiedad overflow

+ +

La propiedad {{cssxref ("overflow")}} es el modo como tomas el control del desbordamiento de un elemento y le dices al navegador cómo desea que se comporte. El valor predeterminado para la propiedad overflow es visible, por lo que, de forma predeterminada vamos a poder ver cuándo se desborda nuestro contenido.

+ +

Si deseas cortar el contenido cuando se desborda, puedes establecer el valor overflow: hidden en tu caja, que hace exactamente lo que dice: ocultar el desbordamiento. Esto puede hacer que las cosas desaparezcan, por lo que solo debes utilizar esta opción si ocultar contenido no te va a causar ningún problema.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/hidden.html", '100%', 600)}}

+ +

Quizás te gustaría añadir barras de desplazamiento cuando el contenido se desborde. Si usas overflow: scroll, tu navegador siempre mostrará barras de desplazamiento, incluso cuando no haya suficiente contenido para que pueda desbordarse. Es posible que desees hacer esto, porque evita que aparezcan y desaparezcan barras de desplazamiento según el contenido.

+ +

Si en la caja siguiente eliminas parte del contenido, observarás que las barras de desplazamiento permanecen aun sin que haya nada que desplazar (o, como mucho, solo las pistas de la barra de desplazamiento).

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/scroll.html", '100%', 600)}}

+ +

En el ejemplo anterior solo necesitamos desplazarnos en el eje y, sin embargo, obtenemos barras de desplazamiento en ambos ejes. En su lugar, puedes usar la propiedad {{cssxref ("overflow-y")}}, y establecer overflow-y: scroll para poder desplazarte solo por el eje y.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/scroll-y.html", '100%', 600)}}

+ +

También puedes desplazarte por el eje x usando {{cssxref ("overflow-x")}}, aunque esta no es una forma recomendada para manejar palabras largas. Si necesitas lidiar con una palabra larga en una caja pequeña, puedes consultar las propiedades {{cssxref ("word-break")}} o {{cssxref ("overflow-wrap")}}. Además, algunos de los métodos expuestos en el artículo Elementos de dimensionado en CSS pueden ayudarte a crear cuadros que se adapten mejor a cantidades variables de contenido.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/scroll-x.html", '100%', 500)}}

+ +

Al igual que con el desplazamiento, obtendrás una barra de desplazamiento en la dimensión de desplazamiento independientemente de si hay suficiente contenido para provocar una barra de desplazamiento.

+ +
+

Nota: observa que puedes especificar un desplazamiento en x y en y utilizando la propiedad overflow y pasando dos valores. Si especificas dos palabras clave, la primera se aplica a overflow-x y la segunda a overflow-y. De lo contrario, tanto overflow-x como overflow-y se fijan en el mismo valor. Por ejemplo, overflow: scroll hidden establece overflow-x en scroll y overflow-y en hidden.

+
+ +

Si deseas que aparezcan barras de desplazamiento solo si hay más contenido del que cabe en la caja, utiliza overflow: auto. En este caso, el navegador decide si muestra las barras de desplazamiento o no. Los navegadores de escritorio solo suelen hacerlo cuando hay contenido suficiente para causar desbordamiento.

+ +

En el ejemplo siguiente, elimina parte del contenido hasta que quepa en la caja y observarás que las barras de desplazamiento desaparecen.

+ +

{{EmbedGHLiveSample("css-examples/learn/overflow/auto.html", '100%', 600)}}

+ +

overflow establece un contexto de formato de bloque

+ +

En CSS hay un concepto conocido como block formatting context o BFC (contexto de formato de bloque). No es algo de lo que debas preocuparte demasiado en este momento, pero es útil saber que cuando usas un valor de overflow, como scroll o auto, creas un BFC. El resultado es que el contenido de la caja al que acabas de cambiar el valor overflow se convierte en un minidiseño propio. Las cosas que están fuera del contenedor no pueden meterse en él, y nada puede sobresalir de esa caja hacia el diseño circundante. Esto es para permitir un comportamiento con desplazamiento, porque para poder crear una experiencia de desplazamiento consistente todo el contenido de tu caja ha de estar contenido en algo, y no puede superponerse con otros elementos de la página.

+ +

Desbordamiento no deseado en diseño web

+ +

Los métodos de diseño modernos (explicados en el módulo Diseñar con el CSS) gestionan muy bien el desbordamiento. Han sido diseñados para hacer frente al hecho de que tendemos a no poder predecir cuánto contenido habrá en la web. Sin embargo, en el pasado, los desarrolladores a menudo usaban alturas fijas para tratar de alinear los fondos de cajas que en realidad no tenían relación entre sí. Este método era frágil y, en una aplicación heredada, ocasionalmente puede aparecer una caja en que el contenido se superpone a otro contenido de la página. Si ves esto, sabrás que se trata de desbordamiento. Lo ideal sería volver a calcular el diseño para no tener que confiar tamaños de caja fijos.

+ +

Al desarrollar un sitio web, siempre debes tener en cuenta los problemas de desbordamiento. Debes probar diseños con cantidades grandes y pequeñas de contenido, aumentar el tamaño de letra... y asegurarte de que tu CSS puede hacerle frente sin ningún problema. Es probable que cambiar el valor de overflow para ocultar contenido o añadir barras de desplazamiento sea algo que debas reservar solo para unos pocos casos especiales, en que realmente desees una caja con barra de desplazamiento, por ejemplo.

+ +

Pon a prueba tus conocimientos

+ +

Hay mucho que absorber en esta lección. ¿Recuerdas la información más importante? Para comprobarlo, ve a Test your skills: overflow.

+ +

Resumen

+ +

Este breve artículo ha introducido el concepto de desbordamiento; ahora comprendes que el CSS intenta no hacer invisible el desbordamiento de contenido, porque esto provoca la pérdida de datos. Has descubierto que puedes gestionar el desbordamiento potencial y también que debes probar tu trabajo para asegurarte de que no causa un desbordamiento problemático accidentalmente.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Handling_different_text_directions", "Learn/CSS/Building_blocks/Values_and_units", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Valores y unidades
  14. +
  15. Elementos de dimensionado en el CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Estilo de las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/depurar_el_css/index.html b/files/es/learn/css/building_blocks/depurar_el_css/index.html new file mode 100644 index 0000000000..5f04fdd756 --- /dev/null +++ b/files/es/learn/css/building_blocks/depurar_el_css/index.html @@ -0,0 +1,198 @@ +--- +title: Depurar el CSS +slug: Learn/CSS/Building_blocks/Depurar_el_CSS +translation_of: Learn/CSS/Building_blocks/Debugging_CSS +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Styling_tables", "Learn/CSS/Building_blocks/Organizing", "Learn/CSS/Building_blocks")}}
+ +

Al escribir CSS te puedes encontrar que, a veces, alguna parte de tu CSS no hace lo que esperas. Tal vez creas que cierto selector debería coincidir con un elemento, pero no sucede nada; o una caja tiene un tamaño diferente al que esperabas. Este artículo te orientará sobre cómo solucionar un problema de CSS y te mostrará cómo las DevTools incluidas en todos los navegadores modernos pueden ayudarte a descubrir qué sucede.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con el CSS).
Objetivo:Conocer los conceptos básicos de las DevTools que hay en los navegadores y de cómo inspeccionar y editar el CSS de un modo fácil.
+ +

Cómo acceder a las DevTools de los navegadores

+ +

El artículo ¿Qué son las herramientas de desarrollo de los navegadores? es una guía actualizada que explica cómo acceder a las herramientas en varios navegadores y plataformas. Si bien puedes optar por desarrollar principalmente en un navegador en particular y, por lo tanto, te familiarizarás más con las herramientas incluidas en ese navegador, vale la pena saber cómo acceder a ellas en otros navegadores. Esto ayudará si haces pruebas de las representaciones que dan diferentes navegadores.

+ +

También te darás cuenta de que los diversos navegadores han optado por centrarse en áreas diferentes al crear sus DevTools. Por ejemplo, en Firefox hay algunas herramientas excelentes para trabajar visualmente con la compaginación con CSS, que te permiten inspeccionar y editar Compaginaciones de cuadrícula, Flexbox y formas. Sin embargo, todos los navegadores tienen herramientas fundamentales similares. Por ejemplo, para inspeccionar las propiedades y los valores que se aplican a los elementos de tu página, y hacer cambios desde el editor.

+ +

En este artículo veremos algunas características útiles de Firefox DevTools para trabajar con CSS. Para hacerlo, usaremos un archivo de ejemplo. Carga esto en una pestaña nueva si deseas seguir adelante y abre tus DevTools como se describe en el artículo del enlace anterior.

+ +

El DOM y "View Source"

+ +

Algo que puede hacer tropezar a los recién llegados a DevTools es la diferencia entre lo que ves cuando miras el código fuente de una página web, o miras el archivo HTML que colocas en el servidor, y lo que puedes ver en la ventana HTML de DevTools. Aunque ves más o menos lo mismo que puedes ver desde View Source (Ver código fuente de la página), hay algunas diferencias.

+ +

En el DOM procesado, el navegador puede haber corregido algunos HTML mal escritos por ti. Si cerraste un elemento incorrectamente, por ejemplo, por abrir con un <h2> y cerrar con un </h3>, el navegador descubre lo que ibas a hacer y el HTML del DOM cerrará ese <h2> de apertura correctamente con un </h2>. El navegador también normaliza todo el HTML, y el DOM también muestra los cambios que hace JavaScript.

+ +

En comparación, View Source es simplemente el código fuente HTML tal como está almacenado en el servidor. El árbol HTML de tus DevTools muestra exactamente lo que el navegador representa en un momento dado, y te da una idea de lo que sucede en realidad.

+ +

Inspección del CSS aplicado

+ +

Selecciona un elemento de tu página, ya sea haciendo clic con el botón derecho o pulsando la tecla ctrl para seleccionar la opción Inspect, o seleccionándolo del árbol HTML que hay a la izquierda de la pantalla de la interfaz DevTools. Selecciona el elemento con la clase box1; este es el primer elemento de la página con una caja alrededor.

+ +

La página de ejemplo para este tutorial con DevTools abiertas.

+ +

Si observasla  vista de reglas, que está a la derecha de tu HTML, deberías poder ver las propiedades y los valores CSS aplicados sobre ese elemento. Verás las reglas aplicadas directamente a la clase box1 y también el CSS que la caja hereda de su elemento padre, en este caso <body>. Esto es útil para cuando ves que se aplica un CSS que no esperabas. Tal vez se esté heredando de un elemento padre y necesites añadir una regla para sobrescribirlo en el contexto de este elemento.

+ +

También es útil la capacidad de expandir las propiedades abreviadas. En nuestro ejemplo se usa la abreviación margin.

+ +

Haz clic en la pequeña flecha para expandir la vista, que muestra las diferentes propiedades sin abreviar y sus valores.

+ +

Puedes activar y desactivar los valores en la vista de reglas, cuando ese panel esté activo; si mantienes el ratón sobre él, aparecerán casillas de verificación. Desmarca la casilla de verificación de una regla, por ejemplo border-radius, y el CSS dejará de aplicarse.

+ +

Puedes usar esto para hacer una comparación entre A y B, decidir si algo se ve mejor con una regla aplicada o sin aplicar, y también para ayudar a depurarlo. Por ejemplo, si un diseño falla e intentas determinar qué propiedad causa el problema.

+ +

Editar valores

+ +

Además de activar y desactivar las propiedades, puedes editar sus valores. ¿Quieres ver si quizá otro color se ve mejor, o deseas modificar algún tamaño? Las DevTools pueden ahorrarte mucho tiempo a la hora de editar una hoja de estilo y volver a cargar la página.

+ +

Selecciona box1 y haz clic en la muestra (el pequeño círculo de color) que muestra el color aplicado al borde. Se abrirá un selector de color y puedes probar con colores diferentes, que se actualizarán en tiempo real en la página. De manera similar puedes cambiar el ancho o el estilo del borde.

+ +

Ventana de aplicación de estilos de DevTools con un selector de color abierto.

+ +

Añadir una propiedad nueva

+ +

Puedes añadir propiedades usando las DevTools. ¿Te has dado cuenta de que quizá no quieres que tu caja herede el tamaño de letra del elemento <body> y quieres establecer tu propio tamaño de letra específico? Pruébalo en DevTools antes de añadirlo a tu archivo CSS.

+ +

Puedes hacer clic en la llave de cierre de la regla para comenzar a introducir una declaración nueva, y en ese momento puedes comenzar a escribir la nueva propiedad y DevTools te mostrará una lista de propiedades coincidentes que se completará automáticamente. Después de seleccionar font-size, introduce el valor que deseas probar. También puede hacer clic en el botón + para añadir una regla adicional con el mismo selector y tus reglas nuevas.

+ +

La ventana DevTools, que añade una propiedad nueva a las reglas, con el autocompletado para font-open

+ +
+

Nota: También hay otras funciones útiles en la vista de reglas; por ejemplo, las declaraciones con valores no válidos están tachadas. Puedes obtener más información en Examinar y editar CSS.

+
+ +

Comprender el modelo de cajas

+ +

En artículos anteriores hemos expuesto el modelo de cajas, y el hecho de que tengamos un modelo de cajas alternativo que cambia la forma en que se calcula el tamaño de los elementos en función del tamaño que les asignas, más el relleno y los bordes. Las DevTools realmente pueden ayudarte a comprender cómo se calcula el tamaño de un elemento.

+ +

El panel de disposición muestra un diagrama del modelo de cajas en el elemento seleccionado, junto con una descripción de las propiedades y los valores que cambian la forma en que el elemento se presenta. Esto incluye una descripción de las propiedades que puedes no haber utilizado explícitamente en el elemento, pero que tienen valores iniciales establecidos.

+ +

En esta ventana, una de las propiedades que se detallan es la propiedad box-sizing, que controla qué modelo de cajas usa el elemento.

+ +

Compara las dos cajas con las clases box1 y box2. Ambas tienen el mismo ancho aplicado (400 px), sin embargo, box1 es visualmente más ancha. En la ventana de diseño puedes ver que usa content-box. Este es el valor que toma el tamaño que asignas al elemento y luego añade el área de relleno y el ancho del borde.

+ +

El elemento con una clase box2 usa border-box, por lo que aquí el área de relleno y el borde se restan del tamaño que has asignado al elemento. Esto significa que el espacio que la caja ocupa en la página es el tamaño exacto que se ha especificado, en nuestro caso width: 400px.

+ +

La ventana de diseño de DevTools

+ +
+

Nota: Descubre más en Examinar e inspeccionar el modelo de cajas.

+
+ +

Resolver problemas de especificidad

+ +

A veces, durante el desarrollo, pero en particular cuando necesitas editar el CSS de un sitio ya publicado, te resultará difícil conseguir que se aplique un determinado CSS. No importa lo que hagas, el elemento simplemente no parece aceptar tu CSS. Lo que suele suceder aquí es que un selector más específico anula tus cambios, y en este caso DevTools te será de gran ayuda.

+ +

En nuestro archivo de ejemplo hay dos palabras incluidas en un elemento <em>. Uno se muestra en color naranja y el otro en rosa. En el CSS hemos aplicado:

+ +
em {
+  color: hotpink;
+  font-weight: bold;
+}
+ +

Sin embargo, un poco más arriba en la hoja de estilo hay una regla con un selector .special:

+ +
.special {
+  color: orange;
+}
+ +

Como recordarás del artículo sobre cascada y herencia, en que hablamos sobre la especificidad, los selectores de clase son más específicos que los selectores de elemento, por lo que este es el valor que se aplica. DevTools puede ayudarte a encontrar estos problemas, especialmente si la información está oculta en algún lugar de una extensa hoja de estilo.

+ +

Inspecciona <em> con la clase .special y DevTools te mostrará que el naranja es el color que se aplica, y también te muestra la propiedad color aplicada al em tachado. Aquí puedes ver que la clase anula el selector de elemento.

+ +

Selecciona un em y mira en DevTools qué solapa el color.

+ +

Descubre más sobre las DevTools de Firefox

+ +

Hay mucha información aquí en MDN sobre las DevTools de Firefox. Echa un vistazo a la sección principal de las DevTools, y consulta las Guías prácticas para obtener información más detallada sobre las cosas que hemos expuesto brevemente en este artículo.

+ +

Problemas al depurar en CSS

+ +

Las DevTools pueden ser de gran ayuda a la hora de resolver problemas con el CSS, pero ¿cómo resuelves una situación en la que el CSS no se comporta como esperas? Los siguientes pasos deberían ayudarte.

+ +

Aléjate del problema

+ +

Cualquier problema de código puede ser frustrante, especialmente los problemas de CSS, porque a menudo no recibes un mensaje de error que buscar en línea para ayudarte a encontrar una solución. Si te sientes frustrado, aléjate del problema por un tiempo: sal a caminar, tómate una copa, habla con un compañero de trabajo o trabaja en otra cosa por un tiempo. A veces, la solución aparece mágicamente cuando dejas de pensar en el problema, e incluso si no llega, trabajar en ello cuando te sientas más fresco te será mucho más fácil.

+ +

¿Tu HTML y CSS son válidos?

+ +

Los navegadores esperan que tu CSS y HTML estén escritos correctamente, sin embargo, los navegadores también son muy indulgentes y harán todo lo posible para mostrar tus páginas web incluso si tiene errores en el marcado o en la hoja de estilo. Si tienes errores en el código, el navegador trata de adivinar lo que quieres decir, y podría tomar una decisión diferente a lo que tenías en mente. Además, dos navegadores diferentes pueden hacer frente al problema de dos maneras diferentes. Por lo tanto, un buen primer paso es pasar tu HTML y CSS por un validador, que detectar cualquier error.

+ + + +

¿La propiedad y el valor son compatibles con el navegador?

+ +

Los navegadores simplemente ignoran el CSS que no entienden. Si la propiedad o el valor que utilizas no es compatible con el navegador en el que lo pruebas, no se romperá nada, pero ese CSS no se aplicará. Las DevTools en general destacan de alguna manera las propiedades y los valores que no son compatibles. En la captura de pantalla siguiente, el navegador no admite el valor de subcuadrícula {{cssxref ("grid-template-columns")}}.

+ +

Imagen de las DevTools del navegador con la cuadrícula-plantilla-columnas: subcuadrícula tachada porque el valor de la subcuadrícula no es compatible.

+ +

También puedes echar un vistazo a las tablas de compatibilidad de navegadores en la parte inferior de cada página de propiedades del proyecto MDN. Te muestran la compatibilidad de cada navegador para esa propiedad, a menudo desglosado si hay compatibilidad para un uso de la propiedad y no para otros. La tabla siguiente muestra los datos de compatibilidad para la propiedad {{cssxref ("shape-outside")}}.

+ +

{{compat("css.shape-outside")}}

+ +

¿Hay algo más que anule tu CSS?

+ +

Aquí es donde la información que has aprendido sobre la especificidad será muy útil. Si tienes algo más específico que anula lo que intentas hacer, puedes entrar en un juego muy frustrante de tratar de resolverlo sin saber qué tienes que resolver. Sin embargo, como hemos dicho, las DevTools te mostrarán qué CSS se ha aplicado y así puedes averiguar cómo hacer que el nuevo selector sea lo suficientemente específico como para anularlo.

+ +

Haz un caso de prueba reducido del problema

+ +

Si el problema no se resuelve con los pasos anteriores, deberás investigar un poco más. Lo mejor que puedes hacer en este momento es crear lo que se conoce como un caso de prueba reducido. Ser capaz de «reducir un problema» es una habilidad muy útil. Te ayudará a encontrar problemas en tu propio código y en el de tus colegas, y también te permitirá informar de errores y solicitar ayuda de manera más efectiva.

+ +

Un caso de prueba reducido es un ejemplo de código que muestra el problema de la manera más simple posible, sin contenido ni estilo circundante. Esto significa a menudo sacar el código problemático de tu diseño para hacer un pequeño ejemplo que solo muestre ese código o característica.

+ +

Para crear un caso de prueba reducido:

+ +
    +
  1. Si tu marcado se genera dinámicamente, por ejemplo desde un CMS, crea una versión estática de la salida que muestre el problema. Un sitio para compartir código como CodePen es útil para alojar casos de prueba reducidos, porque son accesibles en línea y puedes compartirlos fácilmente con tus colegas. Puedes comenzar por hacer un View Source de la página y copiar el HTML en CodePen, luego toma cualquier CSS y JavaScript relevante e inclúyelo también. Después de eso, puedes verificar si el problema sigue ahí.
  2. +
  3. Si eliminar el JavaScript no soluciona el problema, no incluyas el JavaScript. Si eliminar el JavaScript hace desaparecer el problema, elimina la mayor cantidad de JavaScript que puedas; deja solo las causas del problema.
  4. +
  5. Elimina cualquier HTML que no contribuya al problema. Elimina componentes o incluso elementos principales del diseño. Nuevamente, intenta reducir al mínimo la cantidad de código que aún muestra el problema.
  6. +
  7. Elimina cualquier CSS que no afecte al problema.
  8. +
+ +

En el proceso, puedes descubrir qué causa el problema, o al menos ser capaz de ponerlo o quitarlo al eliminar algo específico. Vale la pena añadir algunos comentarios a tu código a medida que vas descubriendo cosas. Si tienes que pedir ayuda, estos comentarios indicarán a la persona que te ayuda lo que ya has intentado. Esto puede proporcionarte bastante información para permitirte buscar posibles problemas por sondeo y soluciones alternativas.

+ +

Si todavía tienes dificultades para solucionar el problema, tener un caso de prueba reducido te ofrece algo con lo que pedir ayuda, publicarlo en un foro o mostrarlo a un compañero de trabajo. Es mucho más probable que obtengas ayuda si antes de pedir la ayuda muestras que has hecho el trabajo de reducir el problema e identificar dónde sucede exactamente. Un desarrollador más experimentado va a poder detectar el problema con rapidez y orientarte en la dirección correcta, y aunque no sea así, echarle un vistazo rápido a tu caso de prueba reducido y, con suerte, ofrecerte al menos algo de ayuda.

+ +

En el caso de que tu problema sea en realidad un error en un navegador, también puedes usar un caso de prueba reducido para presentar un informe de error al proveedor del navegador correspondiente (por ejemplo, en el sitio de Bugzilla de Mozilla).

+ +

A medida que adquieras más experiencia con CSS, descubrirás que vas adquiriendo rapidez para descubrir de dónde vienen los problemas. Sin embargo, incluso los más experimentados a veces nos preguntamos qué pasa. Adoptar un enfoque metódico, hacer un caso de prueba reducido y explicar el problema a otra persona suele dar un buen resultado para encontrar una solución.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Styling_tables", "Learn/CSS/Building_blocks/Organizing", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/dimensionar_elementos_en_css/index.html b/files/es/learn/css/building_blocks/dimensionar_elementos_en_css/index.html new file mode 100644 index 0000000000..81759abccc --- /dev/null +++ b/files/es/learn/css/building_blocks/dimensionar_elementos_en_css/index.html @@ -0,0 +1,129 @@ +--- +title: Dimensionar elementos en CSS +slug: Learn/CSS/Building_blocks/Dimensionar_elementos_en_CSS +translation_of: Learn/CSS/Building_blocks/Sizing_items_in_CSS +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Values_and_units", "Learn/CSS/Building_blocks/Images_media_form_elements", "Learn/CSS/Building_blocks")}}
+ +

En los diversos artículos vistos hasta ahora, has aprendido varias formas de dimensionar elementos en una página web utilizando CSS. Es importante que comprendas qué tamaños van a tener los diferentes elementos de tu diseño, y en este artículo vamos a resumir las diversas formas en que puedes asignar tamaños a los elementos con CSS y definir algunos términos relativos al dimensionado que te ayudarán en el futuro.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Comprender las diferentes formas en que podemos dimensionar las cosas en CSS.
+ +

El tamaño natural o intrínseco de las cosas

+ +

Los elementos HTML tienen un tamaño natural, establecido antes de que se vean afectados por cualquier código CSS. Un ejemplo sencillo es una imagen. Una imagen tiene un ancho y una altura que están definidos en el archivo de imagen que está incrustando en la página. Este tamaño se describe como el tamaño intrínseco, que proviene de la imagen misma.

+ +

Si colocas una imagen en una página y no cambias su altura y ancho, ya sea usando atributos en la etiqueta <img> o el CSS, se mostrará con ese tamaño intrínseco. En el ejemplo siguiente le hemos dado un borde a la imagen para que puedas ver la extensión del archivo.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/intrinsic-image.html", '100%', 600)}}

+ +

Sin embargo, un elemento {{htmlelement ("div")}} vacío no tiene tamaño propio. Si añades un elemento {{htmlelement ("div")}} sin contenido a tu HTML, entonces debes darle un borde como hemos hecho con la imagen y verás una línea en la página. Se trata del borde del elemento replegado sobre sí mismo porque no hay contenido para mantenerlo abierto. En nuestro ejemplo siguiente, ese borde se extiende por todo el ancho del contenedor, porque es un elemento de nivel de bloque, un comportamiento con el que deberías comenzar a familiarizarte. No tiene altura (o tamaño en la dimensión de bloque) porque no hay contenido.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/intrinsic-text.html", '100%', 500)}}

+ +

En el ejemplo anterior, añade texto al elemento vacío. Ahora el borde contiene ese texto porque la altura del elemento queda definida por el contenido. Por lo tanto, el tamaño de este elemento <div> en la dimensión del bloque proviene del tamaño del contenido. Nuevamente, este es el tamaño intrínseco del elemento: su tamaño está definido por su contenido.

+ +

Configurar un tamaño específico

+ +

Por supuesto, podemos dar a los elementos de nuestro diseño un tamaño específico. Cuando asignas un tamaño a un elemento (al cual deberá ajustarse el contenido del elemento) nos referimos a este como tamaño extrínseco. Toma nuestro elemento <div> del ejemplo anterior: podemos darle valores específicos como {{cssxref ("width")}} y {{cssxref ("height")}}, y así tendrá ese tamaño sea cual sea su contenido. Como descubrimos en nuestro artículo anterior sobre el desbordamiento, una altura establecida puede causar el desbordamiento del contenido si hay más contenido del que cabe en el elemento.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/height.html", '100%', 600)}}

+ +

Debido a este problema de desbordamiento, fijar la altura de los elementos con longitudes o porcentajes es algo que debemos hacer con mucho cuidado en la web.

+ +

El uso de porcentajes

+ +

En muchos sentidos, los porcentajes actúan como unidades de longitud, y como discutimos en el artículo sobre valores y unidades, a menudo se pueden usar indistintamente con longitudes. Cuando usas un porcentaje, debes tener claro de qué es porcentaje. En el caso de una caja dentro de otro contenedor, si a la caja secundaria le asignas un porcentaje al ancho, será un porcentaje del ancho del contenedor principal.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/percent-width.html", '100%', 600)}}

+ +

Esto se debe a que los porcentajes se refieren al tamaño del bloque contenedor. Sin un porcentaje aplicado, nuestro elemento <div> ocuparía el 100% del espacio disponible, porque es un elemento de nivel de bloque. Si le damos un ancho porcentual, este se convierte en un porcentaje del espacio que normalmente ocuparía.

+ +

Porcentaje de márgenes y áreas de relleno

+ +

Si configuras margins y padding como un porcentaje, puede que observes un comportamiento extraño. En el ejemplo siguiente hay una caja. Hemos asignado a la caja interna un margen ({{cssxref ("margin")}}) del 10% y una área de relleno ({{cssxref ("padding")}}) del 10%. El área de relleno y el margen de la parte superior e inferior de la caja son del mismo tamaño que el margen de la izquierda y de la derecha.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/percent-mp.html", '100%', 700)}}

+ +

Podrías esperar, por ejemplo, que el porcentaje de los márgenes superior e inferior sea un porcentaje de la altura del elemento, y el porcentaje de los márgenes izquierdo y derecho sea un porcentaje del ancho del elemento. Sin embargo, ¡este no es el caso!

+ +

Cuando utilizas el margen y el área de relleno en porcentajes, el valor se calcula a partir del tamaño en línea del elemento, es decir, el ancho del elemento cuando se trabaja en un lenguaje horizontal. En nuestro ejemplo, todos los márgenes y el área de relleno son del 10% del ancho del elemento. Esto significa que puedes tener márgenes y relleno alrededor de la caja del mismo tamaño. Este es un hecho que vale la pena recordar si utilizas porcentajes de esta manera.

+ +

Tamaños mínimo y máximo

+ +

Además de asignar a las cosas un tamaño fijo, podemos pedirle al CSS que asigne a un elemento un tamaño mínimo o máximo. Si tienes una caja que puede contener una cantidad variable de contenido y deseas que tenga siempre al menos una altura determinada, puedes establecer la propiedad {{cssxref ("min-height")}}. La caja siempre tendrá al menos esta altura, pero crecerá si hay más contenido del que la caja puede contener.

+ +

En el ejemplo siguiente puedes ver dos cuadros, ambos con una altura definida de 150 píxeles. La caja de la izquierda tiene 150 píxeles de alto; la de la derecha contiene contenido que necesita más espacio, por lo que su tamaño supera los 150 píxeles.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/min-height.html", '100%', 800)}}

+ +

Esto es muy útil para trabajar con cantidades de contenido variables y asimismo evitar desbordamientos.

+ +

Un uso común de {{cssxref ("max-width")}} es para reducir el tamaño de las imágenes si no hay suficiente espacio para mostrarlas en su ancho intrínseco, al asegurarte de que no serán mayores que ese ancho.

+ +

A modo de ejemplo, si para una imagen tienes que establecer width: 100% y su ancho intrínseco es menor que su contenedor, la imagen se verá obligada a expandirse y agrandarse, y se pixelará. Si su ancho intrínseco es mayor que su contenedor, se desbordará. No es probable que desees que suceda ninguno de estos casos.

+ +

Si en lugar de ello usas max-width: 100%, la imagen puede encogerse con respecto a su tamaño intrínseco, pero no se agranda más allá del 100% de su tamaño.

+ +

En el ejemplo siguiente hemos utilizado la misma imagen dos veces. La primera imagen tiene width: 100% y está en un contenedor que es más grande, por lo que se extiende hasta el ancho del contenedor. La segunda imagen tiene max-width: 100% y, por lo tanto, no se estira para llenar el recipiente. La tercera caja contiene la misma imagen de nuevo, también con max-width: 100%; pero en este caso puedes ver cómo se ha reducido para encajar en la caja.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/max-width.html", '100%', 800)}}

+ +

Esta técnica se utiliza para dar a las imágenes una respuesta adaptativa, de modo que se reduzcan adecuadamente cuando se visualizan en un dispositivo más pequeño. Sin embargo, no es conveniente usar esta técnica para cargar imágenes demasiado grandes y luego reducirlas en el navegador. Las imágenes deben tener el tamaño adecuado, no deben ser más grandes de lo que sea necesario para el tamaño más grande que se muestran en el diseño. Descargar imágenes muy grandes ralentizará tu sitio y puede costarles más dinero a los usuarios si tienen una conexión tarifada.

+ +
+

Nota: Obtén más información sobre las técnicas adaptativas para las imágenes.

+
+ +

Unidades de ventana gráfica

+ +

La ventana gráfica es el área visible de tu página en el navegador que utilizas para ver un sitio, y también tiene un tamaño. En CSS hay unidades que asociadas con el tamaño de la ventana gráfica: las unidades vw para el ancho y vh para la altura. Con estas unidades puedes establecer tamaños relativos a la ventana gráfica del usuario.

+ +

1vh es igual al 1% de la altura de visualización, y 1vw es igual al 1% de la anchura. Puedes usar estas unidades para dimensionar cajas, pero también texto. En el ejemplo siguiente hay un cuadro que tiene un tamaño de 20vh y 20vw. La caja contiene una letra A, a la que se le ha dado un valor para {{cssxref ("font-size")}} de 10vh.

+ +

{{EmbedGHLiveSample("css-examples/learn/sizing/vw-vh.html", '100%', 600)}}

+ +

Si cambias los valores vh y vw, cambia el tamaño de la caja o de la letra; cambiar el tamaño de la ventana gráfica también cambia esos tamaños porque están dimensionados en relación con el de la ventana gráfica. Para ver el cambio del ejemplo cuando cambias el tamaño de la ventana gráfica, debes cargar el ejemplo en una ventana nueva del navegador, que pueda cambiar de tamaño (ya que tu ventana gráfica es el <iframe> incrustado que contiene el ejemplo que se muestra arriba). Abre el ejemplo, cambia el tamaño de la ventana del navegador y observa lo que ocurre con el tamaño de la caja y el texto.

+ +

Cambiar los tamaños según la ventana gráfica puede ser útil en tus diseños. Por ejemplo, si deseas mostrar una sección principal a pantalla completa antes del resto del contenido, haz que esa parte de tu página de 100vh empuje el resto del contenido por debajo de la ventana gráfica, de modo que solo aparezca cuando desplacen los contenidos del documento con la barra de desplazamiento.

+ +

Resumen

+ +

Este artículo te ha dado un resumen de algunos problemas clave con los que puedes encontrarte al dimensionar cosas en la web. Cuando llegues al artículo Compaginar con CSS, el tamaño va a ser un aspecto muy importante para dominar los diferentes métodos de compaginación, por lo que, antes de continuar, vale la pena comprender los conceptos que hemos expuesto en este artículo.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Values_and_units", "Learn/CSS/Building_blocks/Images_media_form_elements", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/el_modelo_de_caja/index.html b/files/es/learn/css/building_blocks/el_modelo_de_caja/index.html new file mode 100644 index 0000000000..dbc0d644f8 --- /dev/null +++ b/files/es/learn/css/building_blocks/el_modelo_de_caja/index.html @@ -0,0 +1,343 @@ +--- +title: El modelo de caja +slug: Learn/CSS/Building_blocks/El_modelo_de_caja +translation_of: Learn/CSS/Building_blocks/The_box_model +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks")}}
+ +

Todo en CSS tiene una caja alrededor, y comprender estas cajas es clave para poder crear diseños con CSS o para alinear elementos con otros elementos. En este artículo, echaremos un vistazo más de cerca al modelo de cajas en CSS con el que vas a poder crear diseños de compaginación más complejos con una comprensión de cómo funciona y la terminología relacionada.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de cómo trabajar con archivos, conocimientos básicos de HTML (véase Introducción al HTML) y nociones de CSS (véase Primeros pasos con CSS).
Objetivo:Aprender sobre el modelo de cajas en CSS, en qué consiste el modelo de cajas y cómo cambiar al modelo alternativo.
+ +

Cajas en bloque y en línea

+ +

En CSS, en general, hay dos tipos de cajas: cajas en bloque y cajas en línea. Estas características se refieren al modo como se comporta la caja en términos de flujo de página y en relación con otras cajas de la página:

+ +

Si una caja se define como un bloque, se comportará de las maneras siguientes:

+ + + +

A menos que decidamos cambiar el tipo de visualización a en línea, elementos como los encabezados (por ejemplo, <h1>) y todos los elementos <p> usan por defecto block como tipo de visualización externa.

+ +

Si una caja tiene una visualización externa de tipo inline, entonces:

+ + + +

El elemento <a>, que se utiliza para los enlaces, y los elementos <span>, <em> y <strong> son ejemplos de elementos que se muestran en línea por defecto.

+ +

El tipo de caja que se aplica a un elemento está definido por los valores de propiedad {{cssxref ("display")}}, como block y inline, y se relaciona con el valor externo (outer) de visualización (display).

+ +

Aparte: tipos de visualización interna y externa

+ +

En este punto, será mejor que también expliquemos los tipos de visualización interna y externa. Como se mencionó anteriormente, las cajas en CSS tienen un tipo de visualización externa, que define si se trata de una caja en bloque o en línea.

+ +

Sin embargo, las cajas también tienen un tipo de visualización interna, que determina cómo se disponen los elementos dentro de esa caja. De forma predeterminada, los elementos dentro de una caja se presentan en flujo normal, lo que significa que se comportan como otros elementos de tipo en bloque o en línea (como se explicó anteriormente).

+ +

Sin embargo, podemos cambiar el tipo de visualización interna utilizando valores de display, como flex. Si en un elemento establecemos display: flex;, el tipo de visualización externa es de tipo bloque (block), pero el tipo de visualización interna cambia a flexible (flex). Cualquier elemento que sea hijo directo de esta caja pasará a comportarse como un elemento de tipo flex, de acuerdo con las reglas que se establecen en la especificación de Flexbox, tema que veremos más adelante.

+ +
+

Nota: Para obtener más información acerca de los valores de visualización y el modo como funcionan las cajas en las disposiciones en bloque y en línea, echa un vistazo a la guía Disposiciones en bloque y en línea de MDN.

+
+ +

A medida que vayas aprendiendo más detalles sobre el diseño CSS, te irás encontrando con el valor flex y con otros valores internos que puedan presentar tus cajas, por ejemplo, grid.

+ +

Sin embargo, la disposición en bloque y en línea es la forma predeterminada cómo se comportan las cosas en la web; como ya dijimos, a veces esto se conoce como flujo normal, porque nuestras cajas se dispondrán en bloque o en línea, si no reciben ninguna otra instrucción.

+ +

Ejemplos de diferentes tipos de visualización

+ +

Sigamos adelante y veamos algunos ejemplos. A continuación tenemos tres elementos HTML diferentes, todos con visualización externa de tipo block. El primero es un párrafo, que tiene un borde añadido con CSS. El navegador representa esto como una caja en bloque, por lo que el párrafo comienza en una línea nueva y se expande por todo el ancho disponible.

+ +

El segundo es una lista, que se presenta usando display: flex. Esto establece una disposición flexible para los elementos que están dentro del contenedor; sin embargo, la lista en sí misma es una caja que se comporta en bloque y, como el párrafo, se expande por todo el ancho del contenedor y fuerza un salto de línea al llegar al final de línea.

+ +

Debajo hay un párrafo a nivel de bloque, dentro del cual hay dos elementos <span>. Estos elementos normalmente serían de tipo inline; sin embargo, uno de los elementos tiene una clase de bloque, y lo hemos establecido como display: block.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/block.html", '100%', 1000)}} 

+ +

Podemos ver cómo se comportan los elementos inline en el ejemplo siguiente. Los elementos <span> del primer párrafo están en línea de manera predeterminada y, por lo tanto, no fuerzan ningún salto de línea.

+ +

También hay un elemento <ul> que se establece como display: inline-flex, que crea una caja con un comportamiento de tipo en línea alrededor de algunos elementos de tipo flex.

+ +

Finalmente, hay dos párrafos configurados con display: inline. El contenedor flexible en línea y los párrafos fluyen todos juntos en línea, en lugar de dividirse en líneas nuevas como lo harían si se mostraran como elementos de bloque.

+ +

En el ejemplo puedes cambiar display: inline por display: block o display: inline-flex y por display: flex para alternar entre estos modos de visualización.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/inline.html", '100%', 1000)}} 

+ +

En artículos posteriores encontrarás cosas como el diseño flexible. El aspecto clave a recordar aquí es que cambiar el valor de la propiedad display puede cambiar entre el modo de visualización exterior en bloque y en línea de una caja, que cambia la forma en que se presenta junto con otros elementos en la disposición en pantalla.

+ +

En el resto de este artículo, nos concentraremos en el tipo de visualización externa.

+ +

¿Qué es el modelo de cajas CSS?

+ +

El modelo de cajas CSS completo se aplica a cajas que presentan comportamiento en bloque; las cajas con comportamiento en línea solo usan una parte del comportamiento definido en el modelo de cajas. El modelo define cómo funcionan juntas las diferentes partes de una caja (margen, borde, relleno y contenido) para crear una caja que puedas ver en tu página. Para complicarlo un poco más, hay un modelo de cajas estándar y un modelo de cajas alternativo.

+ +

Partes de una caja

+ +

Al hacer una caja de tipo bloque en CSS tenemos los elementos siguientes:

+ + + +

El diagrama siguiente muestra estas capas:

+ +

Diagrama del modelo de cajas

+ +

El modelo de cajas CSS estándar

+ +

En el modelo de cajas estándar, cuando estableces los atributos width y height para una caja, defines el ancho y el alto del contenido de la caja. Cualquier área de relleno y borde se añade a ese ancho y alto para obtener el tamaño total que ocupa la caja. Esto se muestra en la imagen que encontrarás a continuación.

+ +

Si suponemos que la caja tiene el CSS siguiente, que establece los valores para las propiedades width, height, margin, border, y padding:

+ +
.box {
+  width: 350px;
+  height: 150px;
+  margin: 10px;
+  padding: 25px;
+  border: 5px solid black;
+}
+
+ +

El espacio que ocupa nuestra caja usando el modelo de cajas estándar será en realidad de 410 px (350 + 25 + 25 + 5 + 5); y su altura, de 210 px (150 + 25 + 25 + 5 + 5), porque el área de relleno y el borde se añaden al ancho que se utiliza para el contenido de la caja.

+ +

Mostrar el tamaño de la caja cuando se usa el modelo de cajas estándar.

+ +
+

Nota: El margen no se cuenta para el tamaño real de la caja; por supuesto, afecta al espacio total que la caja ocupa en la página, pero solo al espacio de fuera de la caja. El área de la caja se termina en el borde, no se extiende hasta el margen.

+
+ +

El modelo de cajas CSS alternativo

+ +

Podrías pensar que es más bien incómodo tener que sumar el borde y el área de relleno para obtener el tamaño real de la caja, ¡y tienes razón! Por este motivo, CSS introdujo un modelo de caja alternativo algún tiempo después del modelo de cajas estándar. Con este modelo, cualquier ancho es el ancho de la caja visible en la página, por lo tanto, el ancho del área de contenido es ese ancho menos el ancho para el relleno y el borde. El mismo CSS que hemos usado antes daría entonces el resultado siguiente (ancho = 350 px, altura = 150 px).

+ +

Mostrar el tamaño de la caja cuando se usa el modelo de cajas alternativo.

+ +

Por defecto, los navegadores usan el modelo de cajas estándar. Si deseas activar el modelo de cajas alternativo para un elemento, hazlo configurando box-sizing: border-box. Con ello, le dices al navegador que tome como el borde de la caja el área definida por cualquier tamaño que establezcas.

+ +
.box {
+  box-sizing: border-box;
+} 
+ +

Si quieres que todos tus elementos usen el modelo de cajas alternativo (opción común entre los desarrolladores) debes establecer la propiedad box-sizing en el elemento <html>. Luego debes configurar todos los demás elementos para que hereden ese valor, como se ve en el fragmento de código siguiente. Si deseas comprender qué hay detrás, consulta el artículo de CSS-Tricks sobre el tamaño de las cajas.

+ +
html {
+  box-sizing: border-box;
+}
+*, *::before, *::after {
+  box-sizing: inherit;
+}
+ +
+

Nota: Un dato curioso es que Internet Explorer usaba por defecto el modelo de cajas alternativo, y no disponía de ningún mecanismo para cambiarlo.

+
+ +

Jugar con los modelos de cajas

+ +

En el ejemplo siguiente puedes ver dos cajas. Ambas tienen una clase .box, lo que les da los mismos atributos width, height, margin, border y padding. La única diferencia es que la segunda caja se ha configurado para utilizar el modelo de cajas alternativo.

+ +

¿Puedes cambiar el tamaño de la segunda caja (añadiendo CSS a la clase .alternate) para que su anchura y altura coincidan con las de la primera caja?

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/box-models.html", '100%', 1000)}} 

+ +
+

Nota: Puedes encontrar la solución aquí.

+
+ +

Utilizar las DevTools del navegador para ver el modelo de cajas

+ +

Las herramientas del desarrollador de tu navegador pueden facilitar la comprensión del modelo de cajas. Si inspeccionas un elemento con las DevTools de Firefox, puedes ver el tamaño del elemento más su margen, área de relleno y borde. Inspeccionar un elemento de esta manera es un modo excelente de descubrir si tu caja es en realidad del tamaño que crees que es.

+ +

Inspeccionar el modelo de cajas de un elemento utilizando Firefox DevTools

+ +

Márgenes, relleno y bordes

+ +

Ya has visto las propiedades {{cssxref ("margin")}}, {{cssxref ("padding")}} y {{cssxref ("border")}} que usamos en el ejemplo anterior. Las propiedades que hemos usado en ese ejemplo son propiedades abreviadas y nos permiten establecer los cuatro lados de la caja a la vez. Estas propiedades abreviadas también tienen propiedades sin abreviar equivalentes, que permiten tener control sobre los diferentes lados de la caja de forma individual.

+ +

Vamos a explorar estas propiedades más detalladamente.

+ +

Margen

+ +

El margen es un espacio invisible que hay alrededor de la caja. Aleja el resto de elementos de la caja. Los márgenes pueden tener valores positivos o negativos. Establecer un margen negativo para un lado de tu caja puede hacer que se superponga con otros elementos de la página. Tanto si utilizas el modelo de cajas estándar como el alternativo, el margen siempre se añade después de haber calculado el tamaño de la caja que se ve.

+ +

Podemos controlar todos los márgenes de un elemento a la vez usando la propiedad {{cssxref ("margin")}}, o cada lado individualmente usando las propiedades equivalentes sin abreviar:

+ + + +

En el ejemplo siguiente, cambia los valores de margen para ver cómo se empuja la caja debido al espacio que el margen crea o se elimina (si es un margen negativo) entre este elemento y el elemento que lo contiene.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/margin.html", '100%', 1000)}} 

+ +

Colapso del margen

+ +

Un punto clave a la hora de entender los márgenes es el concepto de colapso del margen. Si tienes dos elementos cuyos márgenes se tocan, esos márgenes se combinan para convertirse en un solo margen, cuyo tamaño es el del margen más grande.

+ +

En el ejemplo siguiente hay dos párrafos. El párrafo superior tiene un atributo margin-bottom de 50 píxeles. El segundo párrafo tiene un atributo margin-top de 30 píxeles. Los márgenes colapsan, por lo que el margen real entre las cajas es de 50 píxeles, y no el total de ambos márgenes.

+ +

Pruébalo ajustando el atributo margin-top del segundo párrafo a 0. El margen visible entre los dos párrafos no cambiará, sino que conservará los 50 píxeles fijados en el atributo bottom-margin del primer párrafo.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/margin-collapse.html", '100%', 1000)}} 

+ +

Hay una serie de reglas que establecen cuándo los márgenes colapsan y cuándo no. Para obtener más información, consulta la página web sobre entender el colapso de márgenes. Por ahora solo debes recordar que el colapso de los márgenes es algo que puede suceder. Si creas un espacio con márgenes y no obtienes el espacio que esperas, probablemente es que se haya producido algún colapso de márgenes.

+ +

Bordes

+ +

El borde se dibuja entre el margen y el área de relleno de una caja. Si utilizas el modelo de cajas estándar, el tamaño del borde se añade a los elementos width y height que establecen el alto y el ancho de la caja. Si utilizas el modelo de cajas alternativo, el tamaño del borde reduce el tamaño de la caja de contenido, porque ocupa una parte del alto y el ancho disponibles.

+ +

Hay una gran cantidad de propiedades que sirven para aplicar estilo a los bordes: hay cuatro bordes y cada borde tiene un estilo, un ancho y un color que podemos modificar.

+ +

Puedes establecer el ancho, el estilo o el color de los cuatro bordes a la vez utilizando la propiedad {{cssxref ("border")}}.

+ +

Para establecer las propiedades de cada lado de forma individual, puedes utilizar:

+ + + +

Para establecer el ancho, el estilo o el color de todos los lados, usa lo siguiente:

+ + + +

Para establecer el ancho, el estilo o el color de un solo lado, puedes usar una de las propiedades no abreviadas:

+ + + +

En el ejemplo siguiente, hemos utilizado varios ejemplos de la lista anterior para crear bordes. Juega con las diferentes propiedades para comprobar que entiendes cómo funcionan. Las páginas de MDN sobre las propiedades de los bordes te proporcionan información sobre los diferentes estilos entre los que puedes elegir para los bordes.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/border.html", '100%', 1000)}} 

+ +

Relleno

+ +

El relleno se encuentra entre el borde y el área de contenido. A diferencia de los márgenes, el relleno no puede tomar valores negativos, por lo que el valor debe ser 0 o positivo. Cualquier fondo aplicado a tu elemento se mostrará detrás del área de relleno y, generalmente, se usa para mantener el contenido alejado del borde.

+ +

Podemos controlar el área de relleno para todos los lados de un mismo elemento usando la propiedad {{cssxref ("padding")}}, o para cada lado uno de los lados usando las propiedades equivalentes:

+ + + +

Si cambias los valores para el elleno en la clase .box del ejemplo siguiente, puedes ver que cambia dónde comienza el texto en relación con la caja.

+ +

También puedes cambiar el relleno en la clase .container, que abrirá el espacio entre el contenedor y la caja. El área de relleno se puede cambiar para cualquier elemento y abrirá espacio entre su borde y lo que esté dentro del elemento.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/padding.html", '100%', 800)}} 

+ +

El modelo de cajas y las cajas en línea

+ +

Todo lo anterior se aplica por completo a las cajas en bloque. Algunas de las propiedades también pueden aplicarse a las cajas en línea, como las que crea un elemento <span>.

+ +

En el ejemplo siguiente hay un elemento <span> dentro de un párrafo al que hemos aplicado las propiedades width, height, margin, border, y padding Puedes ver que la anchura y la altura se ignoran. Se respetan el margen, el relleno y el borde, pero no cambian la relación de otro contenido con respecto a nuestra caja en línea, por lo que el relleno y el borde se superponen a otras palabras en el párrafo.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/inline-box-model.html", '100%', 800)}} 

+ +

El uso de display: inline-block

+ +

Hay un valor especial de display que proporciona un punto medio entre inline y block. Esto es útil para situaciones en las que no deseas que un elemento fuerce un salto de línea, pero sí deseas que se respeten las propiedades width y height para evitar superposiciones como la que se ve arriba.

+ +

Un elemento con display: inline-block conforma un subconjunto de los elementos en bloque que ya conocemos:

+ + + +

Sin embargo, no se fuerza un salto de línea, y solo se hace más grande que su contenido si añades las propiedades width y height explícitamente.

+ +

En el ejemplo siguiente hemos añadido display: inline-block a nuestro elemento <span>. Cámbialo por display: block o elimina la línea para ver la diferencia entre ambos modelos de visualización.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/inline-block.html", '100%', 800)}} 

+ +

Esto puede ser útil cuando deseas dar a un enlace un área de impacto más grande añadiendo padding. <a> es un elemento en línea como <span>; puedes usar display: inline-block para configurar el área de relleno para facilitar al usuario hacer clic en el enlace.

+ +

Esto se ve con bastante frecuencia en las barras de navegación. La navegación siguiente se muestra en una fila usando flexbox y hemos añadido una área de relleno al elemento <a> porque queremos poder cambiar su color de fondo (background-color) cuando se pasa el ratón por encima de <a>. El área de relleno parece superponerse al borde del elemento <ul>. Esto se debe a que <a> es un elemento en línea.

+ +

Añade display: inline-block a la regla con el selector .links-list a y verás cómo se soluciona este problema, al hacer que otros elementos respeten el área de relleno.

+ +

{{EmbedGHLiveSample("css-examples/learn/box-model/inline-block-nav.html", '100%', 600)}} 

+ +

Pon a prueba tus habilidades

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más relevante? Encontrarás más pruebas para verificar que has retenido esa información en Test your skills: The Box Model.

+ +

Resumen

+ +

Eso es lo que hay que entender sobre el modelo de cajas. Es posible que en el futuro desees volver a este artículo si alguna vez te lías con los tamaños de las cajas en la disposición de tu página web.

+ +

En el artículo siguiente veremos cómo se pueden usar los fondos y bordes para hacer que tus simples cajas presenten un aspecto más interesante.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/fondos_y_bordes/index.html b/files/es/learn/css/building_blocks/fondos_y_bordes/index.html new file mode 100644 index 0000000000..0de93e1eb1 --- /dev/null +++ b/files/es/learn/css/building_blocks/fondos_y_bordes/index.html @@ -0,0 +1,306 @@ +--- +title: Fondos y bordes +slug: Learn/CSS/Building_blocks/Fondos_y_bordes +translation_of: Learn/CSS/Building_blocks/Backgrounds_and_borders +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks/Handling_different_text_directions", "Learn/CSS/Building_blocks")}}
+ +

En este artículo, veremos algunas de las cosas creativas que puedes hacer con los fondos y los bordes de CSS. Añadir degradados, imágenes de fondo o redondear esquinas; los fondos y los bordes son la solución para una gran cantidad de cuestiones de estilo en CSS.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, conocimientos básicos de HTML (véase Introducción al HTML) y nociones de CSS (véase Primeros pasos con el CSS).
Objetivo:Aprender a diseñar el fondo y los bordes de las cajas.
+ +

Aplicar estilo a los fondos en CSS

+ +

La propiedad {{cssxref ("background")}} de CSS es una propiedad abreviada de una serie de propiedades de fondo que vamos a ver en este artículo. Si descubres una propiedad de fondo compleja en una hoja de estilo, puede parecer un poco difícil de entender porque pueden estarse pasando muchos valores a la vez.

+ +
.box {
+  background: linear-gradient(105deg, rgba(255,255,255,.2) 39%, rgba(51,56,57,1) 96%) center center / 400px 200px no-repeat,
+  url(big-star.png) center no-repeat, rebeccapurple;
+} 
+
+ +

Más adelante en este tutorial regresaremos a cómo funcionan las propiedades abreviadas, pero primero echemos un vistazo a las diferentes cosas que puedes hacer con los fondos en CSS, a partir de observar las propiedades de fondo individuales.

+ +

Los colores de fondo

+ +

La propiedad {{cssxref ("background-color")}} define el color de fondo de cualquier elemento en CSS. La propiedad admite cualquier <color> válido. Un color de fondo (background-color) se extiende por debajo del contenido y el relleno del elemento.

+ +

En el ejemplo siguiente hemos utilizado varios valores de color para añadir un color de fondo a la caja, a un encabezado y a un elemento {{htmlelement ("span")}}.

+ +

Juega un poco con ellos; usa cualquier valor <color> disponible.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/color.html", '100%', 800)}}

+ +

Las imágenes de fondo

+ +

La propiedad {{cssxref ("background-image")}} permite visualizar una imagen de fondo en un elemento. En el ejemplo siguiente hay dos cajas: una tiene una imagen de fondo que es más grande que la caja misma, la otra tiene una imagen pequeña en forma de estrella.

+ +

Este ejemplo demuestra dos cosas sobre las imágenes de fondo. De forma predeterminada, la imagen grande no se reduce para ajustarse a la caja, por lo que solo vemos una pequeña esquina de esta, mientras que la imagen pequeña aparece en forma de mosaico hasta llenar la caja. En este caso, la imagen es en realidad una sola estrella.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/background-image.html", '100%', 800)}}

+ +

Si especificas un color de fondo además de una imagen de fondo, la imagen se muestra encima del color de fondo. Añade una propiedad background-color al ejemplo anterior y obsérvalo en acción.

+ +

Controlar background-repeat

+ +

La propiedad {{cssxref ("background-repeat")}} se usa para controlar el comportamiento de tipo mosaico de las imágenes. Los valores disponibles son:

+ + + +

Prueba estos valores en el ejemplo siguiente. Hemos establecido el valor no-repeat, así que solo verás una estrella. Prueba los diferentes valores (repeat-x y repeat-y) y observa cuáles son los efectos.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/repeat.html", '100%', 800)}}

+ +

Dimensionar la imagen de fondo

+ +

En el ejemplo anterior hay una imagen grande que aparece recortada porque es más grande que el fondo. En este caso, podríamos usar la propiedad {{cssxref ("background-size")}}, que puede tomar valores de longitud o porcentaje, para ajustar el tamaño de la imagen para que quepa dentro del fondo.

+ +

También puedes utilizar palabras clave:

+ + + +

En el ejemplo siguiente hemos usado la imagen más grande del ejemplo anterior y unidades de longitud para establecer sus dimensiones dentro de la caja. Puedes ver que esto ha distorsionado la imagen.

+ +

Prueba lo siguiente:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/size.html", '100%', 800)}}

+ +

Posicionar la imagen de fondo

+ +

La propiedad {{cssxref ("background-position")}} te permite elegir la posición en la que aparece la imagen de fondo dentro de la caja a la que está asociada. Para ello se utiliza un sistema de coordenadas en el que la esquina superior izquierda de la caja es (0,0), y la caja se coloca sobre los ejes horizontal (x) y vertical (y).

+ +
+

Nota: El valor predeterminado de background-position es (0,0).

+
+ +

Los valores de background-position más comunes toman dos valores independientes: un valor horizontal seguido de un valor vertical.

+ +

Puedes usar palabras clave como top y right (busca todas las demás en la página sobre la propiedad {{cssxref ("background-position")}}):

+ +
.box {
+  background-image: url(star.png);
+  background-repeat: no-repeat;
+  background-position: top center;
+} 
+
+ +

Y también longitudes y porcentajes:

+ +
.box {
+  background-image: url(star.png);
+  background-repeat: no-repeat;
+  background-position: 20px 10%;
+} 
+
+ +

También puedes mezclar valores de palabras clave con longitudes o porcentajes, por ejemplo:

+ +
.box {
+  background-image: url(star.png);
+  background-repeat: no-repeat;
+  background-position: top 20px;
+}
+ +

Por último, también puedes usar una sintaxis de 4 valores para indicar una distancia desde ciertos bordes del cuadro: la unidad de longitud en este caso es un desplazamiento del valor que la precede. Entonces, en el CSS siguiente, colocamos el fondo a 20 px desde la parte superior y a 10 px desde la derecha:

+ +
.box {
+  background-image: url(star.png);
+  background-repeat: no-repeat;
+  background-position: top 20px right 10px;
+} 
+ +

Utiliza el ejemplo siguiente para jugar con estos valores y mover la estrella por la caja.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/position.html", '100%', 800)}}

+ +
+

Nota: background-position es una propiedad abreviada de {{cssxref("background-position-x")}} y {{cssxref("background-position-y")}}, que te permiten configurar los diferentes valores de posición del eje por separado.

+
+ +

Degradados de fondo

+ +

Un degradado, cuando se usa para un fondo, actúa como una imagen y también se establece usando la propiedad {{cssxref("background-image")}}.

+ +

Puedes leer más sobre los diferentes tipos de degradados y sobre qué puedes hacer con ellos en la página sobre el tipo de datos <gradient> de MDN. Una forma divertida de jugar con degradados es usar uno de los muchos generadores de degradados CSS que hay disponibles en la web, como este. Puedes crear un degradado y luego copiar y pegar el código fuente que lo genera.

+ +

Prueba algunos degradados diferentes en el ejemplo siguiente. En las dos cajas hay, respectivamente, un degradado lineal que se extiende por toda la caja, y un degradado radial con un tamaño establecido, que por lo tanto se repite.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/gradients.html", '100%', 800)}}

+ +

Múltiples imágenes de fondo

+ +

También es posible poner múltiples imágenes de fondo: puedes especificar múltiples valores background-image para un solo atributo, separados cada uno por una coma.

+ +

Si haces esto, las imágenes de fondo pueden quedar superpuestas entre sí. Los fondos se superponen con la última imagen de fondo que hay en la parte inferior de la lista, y cada imagen anterior se apila encima de la que sigue en el código.

+ +
+

Nota: Los degradados se pueden mezclar con imágenes de fondo normales.

+
+ +

Las otras propiedades background-* también pueden tener valores múltiples separados por comas, de la misma manera que background-image:

+ +
background-image: url(image1.png), url(image2.png), url(image3.png), url(image1.png);
+background-repeat: no-repeat, repeat-x, repeat;
+background-position: 10px 20px,  top right;
+ +

Cada valor de las diversas propiedades coincide con los valores que están en la misma posición en las otras propiedades. Arriba, por ejemplo, el valor para la propiedad background-repeat de image1 será no-repeat. Sin embargo, ¿qué sucede cuando diferentes propiedades tienen una cantidad diferente de valores? La respuesta es que los valores que ocupan las posiciones más pequeñas se alternan cíclicamente: en el ejemplo anterior hay cuatro imágenes de fondo pero solo dos valores background-position. Los primeros dos valores de posición se aplicarán a las dos primeras imágenes, luego los valores volverán a asignarse cíclicamente: a image3 se le dará el primer valor de posición, y a image4 se le dará el segundo valor de posición.

+ +

Vamos a jugar. En el ejemplo siguiente hemos incluido dos imágenes. Para demostrar el orden de superposición, cambia la imagen de fondo que aparece primero en la lista. O juega con las otras propiedades para cambiar la posición, el tamaño o repite los valores.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/multiple-background-image.html", '100%', 800)}}

+ +

Anclaje del fondo

+ +

Otra opción que hay disponible para fondos es especificar cómo se desplazan cuando se desplaza el contenido. Esto se controla con la propiedad {{cssxref ("background-attachment")}}, que puede tomar los valores siguientes:

+ + + +

La propiedad {{cssxref ("background-attachment")}} solo tiene efecto cuando hay contenido por el que puedas desplazarte, por lo que hemos preparado un ejemplo para demostrar las diferencias entre los tres valores: echa un vistazo a background-attachment.html (También puedes consultar el código fuente aquí).

+ +

Usar la propiedad abreviada para el fondo

+ +

Como mencionamos al comienzo de este artículo, a menudo verás fondos que están especificados usando la propiedad {{cssxref ("background")}}. Esta forma abreviada te permite configurar todas las diferentes propiedades a la vez.

+ +

Si utilizas varios fondos, debes especificar todas las propiedades para el primer fondo y luego añadir el fondo siguiente separado por una coma. En el ejemplo siguiente hay un degradado con un tamaño y una posición, luego un fondo de imagen con no-repeat y una posición y, por último, un color.

+ +

Al escribir los valores abreviados de las imágenes de fondo es necesario seguir algunas reglas, por ejemplo:

+ + + +

Consulta la página para el atributo {{cssxref ("background")}} de MDN para ver todas las posibilidades.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/background.html", '100%', 800)}}

+ +

Consideraciones de accesibilidad con los fondos

+ +

Al colocar texto sobre una imagen o un color de fondo, debes asegurarte de que tiene suficiente contraste para que tus visitantes puedan leer el texto. Si estableces una imagen de fondo y el texto se coloca encima de la imagen, también debes especificar un color de fondo (background-color) que permita leer el texto si la imagen no se carga.

+ +

Los lectores de pantalla no pueden analizar las imágenes de fondo, por lo tanto, deben ser puramente decorativas; cualquier contenido importante debe ser parte de la página HTML y no debe estar contenido en un fondo.

+ +

Bordes

+ +

Al aprender sobre el modelo de cajas descubrimos cómo los bordes afectan al tamaño de nuestra caja. En este artículo veremos cómo usar los bordes de una manera creativa. Por lo general, cuando a un elemento le añadimos bordes con CSS, usamos una propiedad abreviada que establece el color, el ancho y el estilo del borde en una línea de CSS.

+ +

Podemos establecer un borde para los cuatro lados de una caja con {{cssxref ("border")}}:

+ +
.box {
+  border: 1px solid black;
+} 
+ +

O podemos establecer solo un borde de la caja, por ejemplo:

+ +
.box {
+  border-top: 1px solid black;
+} 
+ +

Cada una de las propiedades de estas propiedades abreviadas sería:

+ +
.box {
+  border-width: 1px;
+  border-style: solid;
+  border-color: black;
+} 
+ +

Y las no abreviadas:

+ +
.box {
+  border-top-width: 1px;
+  border-top-style: solid;
+  border-top-color: black;
+} 
+ +
+

Nota: Estas propiedades para el borde superior, derecho, inferior e izquierdo también tienen propiedades lógicas asignadas que se relacionan con el modo de escritura del documento (por ejemplo, texto de izquierda a derecha o de derecha a izquierda, o de arriba a abajo). Exploraremos esto en la próxima lección, que expone el uso de diferentes direcciones de texto.

+
+ +

Hay una variedad de estilos que puedes usar para los bordes. En el ejemplo siguiente, hemos utilizado un estilo de borde diferente para los cuatro lados de la caja. Juega con el estilo, el ancho y el color del borde para ver cómo funcionan los bordes.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/borders.html", '100%', 800)}}

+ +

Esquinas redondeadas

+ +

El redondeo de esquinas en una caja se logra mediante el uso de la propiedad {{cssxref ("border-radius")}} y otras propiedades asociadas que se relacionan con cada esquina de la caja. Como valor pueden usarse dos longitudes o porcentajes: el primer valor define el radio horizontal y el segundo el radio vertical. En muchos casos, solo se pondrá un valor, que se utilizará para ambos.

+ +

Por ejemplo, para hacer que las cuatro esquinas de una caja tengan un radio de 10 píxeles:

+ +
.box {
+  border-radius: 10px;
+} 
+ +

O para hacer que la esquina superior derecha tenga un radio horizontal de 1 em y un radio vertical del 10%:

+ +
.box {
+  border-top-right-radius: 1em 10%;
+} 
+ +

En el ejemplo siguiente hemos establecido las cuatro esquinas, y luego cambiamos los valores de la esquina superior derecha para que sea diferente. Juega con los valores para cambiar las esquinas. Echa un vistazo a la página de la propiedad {{cssxref ("border-radius")}} para ver las opciones de sintaxis disponibles.

+ +

{{EmbedGHLiveSample("css-examples/learn/backgrounds-borders/corners.html", '100%', 800)}}

+ +

Pon a prueba tus habilidades

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más relevante? Encontrarás más pruebas para verificar que retienes la información antes de seguir adelante en Test your skills: Backgrounds and Borders.

+ +

Resumen

+ +

En este artículo hemos expuesto bastantes conceptos y puedes ver que hay mucho para añadir a un fondo o a un borde de una caja. Explora las diferentes páginas de propiedades si deseas obtener más información sobre cualquiera de las características que hemos discutido. Todas las páginas de MDN contienen más ejemplos de uso, para que juegues y mejores tus conocimientos.

+ +

En el próximo artículo descubriremos cómo interacciona el modo de escritura de tu documento con tu CSS. ¿Qué sucede cuando el texto no fluye de izquierda a derecha?

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks/Handling_different_text_directions", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git "a/files/es/learn/css/building_blocks/im\303\241genes_medios_y_elementos_de_formulario/index.html" "b/files/es/learn/css/building_blocks/im\303\241genes_medios_y_elementos_de_formulario/index.html" new file mode 100644 index 0000000000..db0f522728 --- /dev/null +++ "b/files/es/learn/css/building_blocks/im\303\241genes_medios_y_elementos_de_formulario/index.html" @@ -0,0 +1,193 @@ +--- +title: 'Imágenes, medios y elementos de formulario' +slug: Learn/CSS/Building_blocks/Imágenes_medios_y_elementos_de_formulario +translation_of: Learn/CSS/Building_blocks/Images_media_form_elements +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Sizing_items_in_CSS", "Learn/CSS/Building_blocks/Styling_tables", "Learn/CSS/Building_blocks")}}
+ +

En este artículo vamos a ver cómo se tratan ciertos elementos especiales en CSS. Las imágenes y otros medios y los elementos de formulario presentan un comportamiento algo distinto que otros elementos CSS, como las cajas, en cuanto a aplicación de estilo. Comprender qué es y qué no es posible te ahorrará frustraciones, y en este artículo vamos a destacar algunas de las cuestiones principales que necesitas saber.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, conocimientos básicos de HTML (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Comprender el modo en que algunos elementos se comportan de manera inusual cuando se diseñan con CSS.
+ +

Elementos de reemplazo

+ +

Las imágenes y los vídeos se describen como elementos de reemplazo. Esto significa que el CSS no puede intervenir en aspectos del diseño interno de estos elementos, sino solo a su posición en la página y algunos otros aspectos. Sin embargo, como veremos, hay varias cosas que el CSS puede hacer con una imagen.

+ +

También se describen ciertos elementos de reemplazo que, como las imágenes y vídeos, presentan una relación de aspecto. Esto significa que tienen un tamaño definido tanto en la dimensión horizontal (x) como en la vertical (y), y por defecto se mostrarán con las dimensiones intrínsecas del archivo.

+ +

El tamaño de las imágenes

+ +

Como ya conoces de estos artículos, todo en CSS genera una caja. Si colocas una imagen dentro de una caja que es más pequeña o más grande que las dimensiones intrínsecas del archivo de imagen en cualquier dirección, aparecerá más pequeño que la caja o se desbordará. Debes decidir qué hacer con el desbordamiento.

+ +

En el ejemplo siguiente hay dos cajas, ambas de 200 píxeles de tamaño:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/images/size.html", '100%', 1000)}}

+ +

¿Qué podemos hacer con el problema del desbordado?

+ +

Como aprendimos en nuestro artículo anterior, una técnica común es hacer que el la propiedad {{cssxref ("max-width")}} de una imagen sea 100%. Esto permite que la imagen tenga un tamaño menor que la caja, pero no que tenga un tamaño mayor. Esta técnica funciona con otros elementos de reemplazo, como <video> o <iframe>.

+ +

Añade max-width: 100% al elemento <img> del ejemplo anterior. Verás que la imagen más pequeña permanece sin cambios, pero la más grande se reduce hasta caber en la caja.

+ +

Puedes tomar otras decisiones sobre las imágenes dentro de los contenedores. Por ejemplo, es posible que desees cambiar el tamaño de una imagen para que cubra una caja por completo.

+ +

La propiedad {{cssxref ("object-fit")}} puede ser de gran ayuda. Cuando se usa object-fit, el elemento de reemplazo puede dimensionarse para adaptarse a una caja de varias maneras.

+ +

A continuación, hemos utilizado el valor cover, que reduce el tamaño de la imagen a la vez que mantiene la relación de aspecto hasta que rellena toda la caja. Al mantenerse la relación de aspecto, la caja corta algunas partes de la imagen.

+ +

{{EmbedGHLiveSample("css-examples/learn/images/object-fit.html", '100%', 1000)}}

+ +

Si usamos el valor contain, la imagen se reduce hasta que es lo bastante pequeña para caber dentro de la caja. Esto puede dar lugar a un formato panorámico si la imagen no presenta la misma relación de aspecto que la caja.

+ +

También puedes probar el valor fill, que rellena la caja, pero no mantiene la relación de aspecto.

+ +

Elementos de reemplazo en una compaginación

+ +

A medida que vayas usando diversas técnicas de diseño CSS en elementos de reemplazo, irás descubriendo que se comportan de manera ligeramente diferente a otros elementos. Por ejemplo, en un diseño flexible o en un diseño de página de cuadrícula, los elementos se expanden por defecto hasta que llenan toda el área. En cambio, las imágenes no se expanden, sino que se alinean con el inicio del área de la cuadrícula o del contenedor flexible.

+ +

Puedes ver esto en el ejemplo siguiente, en que hay un contenedor de con dos columnas y dos filas, que tiene cuatro elementos. Todos los elementos <div> tienen un color de fondo y se estiran para llenar la fila y la columna. La imagen, sin embargo, no se expande.

+ +

{{EmbedGHLiveSample("css-examples/learn/images/layout.html", '100%', 1000)}}

+ +

Si sigues estos artículos en orden, no habrás llegado todavía a la compaginación. Ten en cuenta solo que cuando los elementos de reemplazo forman parte de una cuadrícula o un diseño flexible, presentan comportamientos predeterminados diferentes, en esencia para evitar que el diseño los expanda de manera extraña.

+ +

Para forzar que la imagen se expanda para llenar la celda de la cuadrícula en la que se encuentra, tendrías que hacer algo como lo siguiente:

+ +
img {
+  width: 100%;
+  height: 100%;
+}
+ +

Sin embargo, esto deformaría la imagen, por lo que probablemente no es lo que querrías hacer.

+ +

Los elementos de formulario

+ +

Los elementos de formulario pueden ser un problema si queremos diseñar con CSS, y el artículo sobre formularios web contiene guías detalladas sobre los aspectos más complicados relativos a este tema, que no vamos a repetir en este artículo. Hay algunos conceptos básicos clave que vale la pena destacar en esta sección.

+ +

Muchos controles de formulario se añaden con el elemento <input>: este elemento define desde campos de formulario simples, como entradas de texto, hasta campos más complejos añadidos en HTML5, como selectores de color y fecha. Hay algunos elementos adicionales, como <textarea> para la entrada de texto multilínea, y también elementos que se utilizan para contener y etiquetar partes de formularios como <fieldset> y <legend>.

+ +

El HTML5 también incluye atributos que permiten a los desarrolladores web indicar qué campos son obligatorios e incluso el tipo de contenido que debe introducirse. Si el usuario añade algo inesperado o deja un campo obligatorio en blanco, el navegador puede mostrar un mensaje de error. Los diversos navegadores no presentan ningún estilo coherente ni ninguna homogeneización en cuanto a la personalización que permiten para tales elementos.

+ +

Aplicar estilo a los elementos de entrada de texto

+ +

Los elementos que permiten la entrada de texto, como <input type="text">, algunos tipos específicos como <input type="email"> y el elemento <textarea> son bastante fáciles de diseñar y tienden a comportarse como otras cajas de tu página. Sin embargo, el estilo predeterminado de estos elementos es diferente según el sistema operativo y el navegador con el que el usuario visite el sitio.

+ +

En el ejemplo siguiente hemos diseñado algunas entradas de texto con CSS: puedes ver que algunos elementos como los bordes, los márgenes y el área de relleno se aplican como es de esperar. Utilizamos selectores de atributos para apuntar a los diferentes tipos de entrada. Intenta cambiar el aspecto de este formulario ajustando los bordes, añadiendo colores de fondo a los campos y cambiando las fuentes y área de relleno.

+ +

{{EmbedGHLiveSample("css-examples/learn/images/form.html", '100%', 1000)}}

+ +
+

¡Importante!: Al cambiar el estilo de los elementos de formulario debes asegurarte de que para el usuario sigue siendo obvio que se trata de elementos de formulario. Podrías crear una entrada de formulario sin bordes y un fondo que sea casi indistinguible del contenido que lo rodea, pero esto haría que sea muy difícil de reconocer y completar.

+
+ +

Como se explica en los artículos sobre el diseño de formularios en la parte HTML de esta web, el sistema operativo presenta muchos de los tipos de entrada más complejos y son inaccesibles para el diseño. Por lo tanto, siempre debes suponer que los formularios se verán de manera bastante diferentes para los distintos visitantes, y deberás probar los formularios complejos en diversos navegadores.

+ +

Herencia y elementos de formulario

+ +

En algunos navegadores, los elementos de formulario no heredan el estilo de letra por defecto. Por lo tanto, si deseas asegurarte de que tus campos de formulario usan la letra que se define para el cuerpo o para un elemento principal, debes añadir esta regla a tu CSS.

+ +
button,
+input,
+select,
+textarea {
+  font-family : inherit;
+  font-size : 100%;
+} 
+ +

Elementos de formulario y tamaño de la caja

+ +

Los elementos de formulario utilizan reglas diferentes en los diversos navegadores para el dimensionado de las cajas de los diferentes controles de formulario. Ya cubrimos la propiedad box-sizing en el artículo sobre el modelo de cajas. Puedes usar este conocimiento cuando diseñes formularios que garanticen una experiencia homogénea en cuanto a los anchos y las alturas de los elementos de formulario.

+ +

Por coherencia, es una buena idea establecer los márgenes y el área de relleno en 0 para todos los elementos, y luego establecerlos de nuevo al diseñar cada uno de los controles de formulario.

+ +
button,
+input,
+select,
+textarea {
+  box-sizing: border-box;
+  padding: 0;
+  margin: 0;
+}
+ +

Otros ajustes útiles

+ +

Además de las reglas ya mencionadas, también debes configurar overflow: auto en <textarea> para que Internet Explorer no muestre una barra de desplazamiento cuando no hay necesidad:

+ +
textarea {
+  overflow: auto;
+}
+ +

Ponerlo todo junto en un «Reinicio»

+ +

Como último paso podemos resumir las diversas propiedades expuestas en el «reinicio de formulario» siguiente para proporcionar una base coherente sobre la que trabajar. Esto incluye todos los elementos mencionados en las tres últimas secciones:

+ +
button,
+input,
+select,
+textarea {
+  font-family: inherit;
+  font-size: 100%;
+  box-sizing: border-box;
+  padding: 0; margin: 0;
+}
+
+textarea {
+  overflow: auto;
+} 
+ +
+

Nota: Muchos desarrolladores utilizan las hojas de estilo de normalización para crear un conjunto de estilos de línea base para usar en todos los proyectos. Por lo general, estas hojas hacen cosas similares a las que acabamos de describir y garantizan que cualquier cosa que pueda ser diferente en distintos navegadores tenga establecido un valor por defecto coherente antes de que tú hagas tu propio trabajo con el CSS. Aunque ya no son tan importantes como lo eran antes, porque los navegadores suelen ser más homogéneos que en el pasado. Sin embargo, si deseas ver un ejemplo, consulta Normalize.css, que es una hoja de estilo muy popular que muchos proyectos utilizan como base.

+
+ +

Para obtener más información sobre los formularios de estilo, echa un vistazo a los dos artículos en la sección HTML de estas guías.

+ + + +

Resumen

+ +

En este artículo hemos destacado algunas de las diferencias que se presentan cuando trabajas con imágenes o media, y otros elementos inusuales, en CSS. En el artículo siguiente veremos algunos consejos que te resultarán útiles cuando tengas que diseñar tablas HTML.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Sizing_items_in_CSS", "Learn/CSS/Building_blocks/Styling_tables", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de cajas
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/index.html b/files/es/learn/css/building_blocks/index.html new file mode 100644 index 0000000000..ce15097a6c --- /dev/null +++ b/files/es/learn/css/building_blocks/index.html @@ -0,0 +1,94 @@ +--- +title: Bloques de construcción CSS +slug: Learn/CSS/Building_blocks +tags: + - Aprender + - CSS + - Principiante + - bloques de construcción +translation_of: Learn/CSS/Building_blocks +--- +
{{LearnSidebar}}
+ +

Este módulo retoma donde Primeros pasos en CSS finalizó — ahora que estás familiarizado con el lenguaje y su sintaxis, y que tienes algo de experiencia en su uso, es hora de bucear un poco más profundo. Este módulo se centra en el estilo en cascada de css y en el concepto de herencia, también veremos todos los tipos de selectores, unidades, tamaños, estilos de fondo, bordes, debugging y mucho más.

+ +

El objetivo aqui es proveerte de herramientas para que puedas escribir código CSS competentemente y ayudarte a entender lo escencial de la teoría antes de centrarnos en disciplinas más específicas como text styling y CSS layout.

+ +

Prerrequisitos

+ +

Antes de comenzar este módulo deberías poseer:

+ +
    +
  1. Un entendimiento básico de la utilización de una computadora y de la
    + navegación web a nivel de usuario.
  2. +
  3. Un entorno básico constituido en base a lo dispuesto en la guía Instalación de software básico, tanto como conocimiento acerca de la creación y la administración de archivos, como es detallado en Dealing with files.
  4. +
  5. Una familiaridad básica con html, como es establecido en el módulo Introdución a HTML.
  6. +
  7. Un entendimiento elemental de CSS, como es discutido en el módulo CSS first steps.
  8. +
+ +
+

Nota: Si estás trabajando en una computadora, tablet, u otro dispositivo en el que no eres capaz de crear tus propios archivos puedes intentar la mayor parte de los ejemplos en código en un programa para trabajar código en linea como JSBin o Glitch.

+
+ +

Guías

+ +

En este módulo encontrarás artículos que cubren los fundamentos más esenciales del lenguaje CSS. A lo largo del módulo encontrarás múltiples ejercicios que te permitirán poner a prueba tu entendimiento.

+ +
+
Cascada y herencia
+
El objetivo de ésta lección es desarrollar tu entendimiento sobre algunos de los conceptos fundamentales de CSS - cascada, especificidad y herencia - los cuales controlan como CSS es aplicado a HTML y como sus conflitos son resueltos.
+
Selectores CSS
+
Hay una gran variedad de selectores disponibles en CSS, permitiendo una fina precision para seleccionar elementos de estilo. En este artículo y sub-artículos, repasaremos los diferentes tipos en detalle y veremos como funcionan. Los sub-artículos son los que siguinetes : + +
+
El modelo de caja
+
Todo en CSS tiene una caja a su alrededor, y comprender estas cajas es clave para poder crear diseños con CSS, o para alinear elementos con otros elementos. En esta lección, analizaremos adecuadamente el modelo CSS Box, para que pueda pasar a tareas de diseño más complejas con una comprensión de cómo funciona y la terminología que se relaciona con él.
+
Fondos y bordes
+
En esta lección, veremos algunas de las cosas creativas que puede hacer con fondos y bordes CSS. Al agregar degradados, imágenes de fondo y esquinas redondeadas, los fondos y los bordes son la respuesta a muchas preguntas de estilo en CSS.
+
Manejo de diferentes direcciones de texto
+
En los últimos años, CSS ha evolucionado para admitir mejor la diferente direccionalidad del contenido, incluyendo Right-to-left (Derecha a Izquierda) pero también de Top-to-bottom (Arriba a abajo ,como el japonés); estas diferentes direccionalidades se llaman modos de escritura. A medida que avance en su estudio y comience a trabajar con el diseño, comprenderá los modos de escritura será muy útil para usted, por lo tanto, los presentaremos en este artículo.
+
Contenido desbordante
+
En esta lección veremos otro concepto importante en CSS: desbordamiento. El Overflow (o desbordamiento) es lo que sucede cuando hay demasiado contenido para contenerlo cómodamente dentro de una caja. En esta guía aprenderá qué es y cómo administrarlo.
+
Valores y unidades de CSS
+
+

Cada propiedad utilizada en CSS tiene un valor o conjunto de valores permitidos para esa propiedad. En esta lección veremos algunos de los valores y unidades más comunes en uso.

+
+
Dimensionar elementos en CSS
+
En las diversas lecciones hasta ahora, ha encontrado varias formas de dimensionar elementos en una página web utilizando CSS. Es importante comprender cuán grandes serán las diferentes características en su diseño, y en esta lección resumiremos las diversas formas en que los elementos obtienen un tamaño a través de CSS y definiremos algunos términos sobre el tamaño que lo ayudarán en el futuro.
+
Imágenes, medios y elementos de forma
+
+

En esta lección veremos cómo se tratan ciertos elementos especiales en CSS. Las imágenes, otros medios y elementos de formulario se comportan de manera un poco diferente en términos de su capacidad para diseñarlos con CSS que los cuadros normales. Comprender qué es y qué no es posible puede ahorrar un poco de frustración, y esta lección resaltará algunas de las cosas principales que necesita saber.

+
+
Dando estilo a una tabla
+
Diseñar una tabla HTML no es el trabajo más glamoroso del mundo, pero a veces todos tenemos que hacerlo. Este artículo proporciona una guía para hacer que las tablas HTML se vean bien, con algunas técnicas específicas de diseño de tablas resaltadas.
+
Depuración de CSS
+
A veces, al escribir CSS, encontrará un problema en el que su CSS no parece estar haciendo lo que espera. Este artículo le dará orientación sobre cómo solucionar un problema de CSS y le mostrará cómo las DevTools incluidas en todos los navegadores modernos pueden ayudarlo a descubrir qué está sucediendo.
+
+
Organizando tu CSS
+
A medida que comience a trabajar en hojas de estilo más grandes y grandes proyectos, descubrirá que mantener un gran archivo CSS puede ser un desafío. En este artículo, analizaremos brevemente algunas de las mejores prácticas para escribir su CSS para que sea fácil de mantener, y algunas de las soluciones que encontrará en uso para ayudar a mejorar la capacidad de mantenimiento.
+
+ +

Evaluaciones

+ +

¿Quieres probar tus habilidades de CSS? Las siguientes evaluaciones pondrán a prueba su comprensión del CSS cubierto en las guías anteriores.

+ +
+
Comprensión de CSS básica
+
Esta evaluación evalúa su comprensión de la sintaxis básica, selectores, especificidad, modelo de caja y más.
+
Crear papel con membrete elegante
+
Si desea causar la impresión correcta, escribir una carta en papel con membrete puede ser un buen comienzo. En esta evaluación, lo retaremos a crear una plantilla en línea para lograr ese aspecto.
+
Una caja de aspecto genial
+
Aquí aprenderás a usar el estilo de fondo y borde para crear un cuadro llamativo.
+
+ +

Ver también

+ +
+
Efectos de estilo avanzados
+
Este artículo actúa como una caja de trucos, brindando una introducción a algunas características de estilo avanzadas e interesantes como sombras de caja, modos de fusión y filtros.
+
diff --git a/files/es/learn/css/building_blocks/manejando_diferentes_direcciones_de_texto/index.html b/files/es/learn/css/building_blocks/manejando_diferentes_direcciones_de_texto/index.html new file mode 100644 index 0000000000..fa21de66e5 --- /dev/null +++ b/files/es/learn/css/building_blocks/manejando_diferentes_direcciones_de_texto/index.html @@ -0,0 +1,165 @@ +--- +title: Manejando diferentes direcciones de texto +slug: Learn/CSS/Building_blocks/Manejando_diferentes_direcciones_de_texto +tags: + - Aprendizaje + - CSS + - Diseño en bloque + - Diseño lineal + - Modos de escritura + - Principiante + - Propiedades lógicas +translation_of: Learn/CSS/Building_blocks/Handling_different_text_directions +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks")}}
+ +

Muchas de las propiedades y valores que hemos encontrado hasta ahora en nuestro aprendizaje de CSS han estado ligadas a las dimensiones físicas de nuestra pantalla. Creamos bordes arriba, a la derecha, abajo y a la izquierda de una caja, por ejemplo. Estas dimensiones físicas se ajustan adecuadamente al contenido que se visualiza de forma horizontal, y por defecto, la web tiende a apoyar lenguajes de izquierda a derecha, como el castellano o el francés, mejor que aquellos que se escriben de derecha a izquierda, como el árabe.

+ +

Sin embargo, en los últimos años, CSS ha evolucionado para soportar de mejor forma contenidos en diferente direccionalidad, incluyendo contenido de derecha a izquierda, pero también de arriba-abajo, como el japonés - Estas direccionalidades se llaman modos de escritura. En la medida que progresa tu estudio y comiences a trabajar con diseños, comprender los modos de escritura será de mucha utilidad para ti, por ello los explicaremos a continuación.

+ + + + + + + + + + + + +
Prerrequisitos:Literatura computacional básica, software básico instalado, conocimiento básico de manejo de archivos, HTML básico (Introducción a HTML), y una idea de cómo funciona CSS (Primeros pasos en CSS.)
Objetivo:Entender la importancia de los modos de escritura en el CSS moderno.
+ +

¿Qué son los modos de escritura?

+ +

Un modo de escritura en CSS se refiere a si el texto está escrito horizontal o verticalmente. La propiedad {{cssxref("writing-mode")}} permite cambiar de un modo a otro. No necesitas estar trabajando en un lenguaje que use un modo de escritura vertical para querer hacer esto - Podrías cambiar el modo de escritura de partes de tu diseño por razones creativas.

+ +

En el ejemplo siguiente existe un encabezado desplegado usando writing-mode: vertical-rl. El texto ahora aparece vertical. El texto vertical es común en diseño gráfico, y puede ser una forma de agregar un aspecto más interesante a tu diseño web.

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/simple-vertical.html", '100%', 800)}}

+ +

Los tres valores posibles para la propiedad writing-mode son:

+ + + +

Así, la propiedad writing-mode está configurando en realidad la direccion en que los elementos de nivel bloque son desplegados en la página - ya sea de arriba abajo, derecha a izquierda, o de izquierda a derecha. Luego señala la dirección del flujo de texto en las frases.

+ +

Modos de escritura y diseño en bloque y lineal.

+ +

Ya hemos visto el diseño en bloque y lineal, y el hecho de que algunas cosas se muestran como elementos de bloque y otras como elementos lineales. Ésto se encuentra ligado al modo de escritura del documento, y no de la pantalla física. Los bloques sólo se presentan desde la parte superior a la inferior de la página si estas usando un modo de escritura que presente el texto horizontalmente, como el español.

+ +

Con el siguiente ejemplo quedará más claro. Si tienes dos cajas que contengan un heading y un paragraph. La primera usa writing-mode: horizontal-tb, un modo de escritura horizontal y desde la parte superior de la página a la base. La segunda usa writing-mode: vertical-rl; este es un modo de escritura vertical y de derecha a izquierda.

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/block-inline.html", '100%', 1200)}}

+ +

Cuando cambiamos el modo de escritura, estamos cambiando que dirección es en bloque y cuál es lineal. En un modo de escritura horizontal-tb El la direccion del bloque va de arriba abajo; en un modo de escritura vertical-rl el bloque corre de derecha a izquierda horizontalmente. De esta forma la dimensión del bloque es siempre la direccion en la que se muestran los bloques en el modo de escritura en uso. La dimensión lineal, es siempre la dirección en que fluye una frase.

+ +

Este dibujo muestra las dos dimensiones en un modo de escritura horizontal.Showing the block and inline axis for a horizontal writing mode.

+ +

Este dibujo muestra las dos dimensiones en un modo de escritura vertical.

+ +

Showing the block and inline axis for a vertical writing mode.

+ +

Una vez que empieces a observar el diseño CSS, y en particular los nuevos métodos de diseño, esta idea de bloque y lineal cobra mayor importancia. Será revisado más adelante.

+ +

Dirección

+ +

Además del modo de escritura también tenemos la dirección del texto. Como se mencionó antes, algunos idiomas como el Árabe se escriben horizontalmente, de derecha a izquierda. Esto no es algo que usarías en un sentido creativo. Si tu simplemente quieres alinear algún elemento a la derecha, existen otras formas de hacerlo. Sin embargo es importante entender esto como parte de la naturaleza del CSS. La web no es solo para lenguajes que son escritos de izquierda a derecha!

+ +

Debido al hecho de que el modo de escritura y la dirección del texto pueden cambiar, los nuevos métodos de diseño CSS no toman como referencia la izquierda y derecha, ni la parte superior e inferior. En su lugar, hablarán de inicio y fin junto con esta idea de en línea y bloque. No te preocupes mucho por eso en este momento, pero ten en cuenta estas ideas a medida que empiezas a mirar el diseño de una página web; va a ser de gran ayuda en tu entendimiento de CSS.

+ +

Valores y propiedades lógicas

+ +

La razón de hablar acerca de modos de escritura y dirección en este punto en tu aprendizaje, es por el hecho de que ya vimos muchas de estas propiedades que están atadas a las dimensiones físicas de la pantalla, y tienen más sentido cuando está en un modo de escritura horizontal.

+ +

Vamos a echarle un vistzo a nuestras dos cajas de nuevo, una con el modo escritura horizontal-tb y otro con vertical-rl. Le hemos dado a estas dos cajas un {{cssxref("width")}}. Puedes ver que cuando la caja está en el modo de escritura vertical, aún tiene una anchura, y esto está causando que el texto se desborde.

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/width.html", '100%', 1200)}}

+ +

Lo que nosotros realmente queremos en este escenario, es esencialmente intercambiar altura y anchura junto con el modo de escritura. Cuando estamos en el modo de escritura vertical, queremos que la caja se expanda en la dimensión del bloque así como lo hace en el modo horizontal.

+ +

Para hacerlo más fácil, CSS ha desarrollado recientemente un conjunto de propiedades asignadas. Estas esencialmente reemplazan las propiedades físicas como width and height, con versiones lógicas o relativas al flujo.

+ +

La propiedad asignada a width cuando está en el modo de escritura horizontal se llama {{cssxref("inline-size")}}, se refiere al tamaño en la dimensión inline. La propiedad para height se llama {{cssxref("block-size")}} y es el tamaño en la dimensión de bloque. Puedes ver como funciona en el ejemplo de abajo, donde reemplazamos width con inline-size.

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/inline-size.html", '100%', 1200)}}

+ +

Propiedades lógicas margin, border y padding

+ +

En las últimas dos lecciones aprendimos acerca del modelo de cajas con CSS, y los bordes CSS. En las propiedades margin, border y padding vas a encontrar varias instancias de propiedades físicas, por ejemplo {{cssxref("margin-top")}}, {{cssxref("padding-left")}}, y {{cssxref("border-bottom")}}. Del mismo modo que tenemos asignaciones para ancho y alto, hay asignaciones para estas propiedades.

+ +

La propiedad margin-top está asignada a {{cssxref("margin-block-start")}}, esto siempre se va a referir al margen al inicio de la dimensión del bloque. 

+ +

La propiedad {{cssxref("padding-left")}} se asigna a {{cssxref("padding-inline-start")}}, el padding que se aplica al inicio de la dirección inline. Aquí será donde las oraciones comienzan en ese modo de escritura. La propiedad {{cssxref("border-bottom")}} se asigna a {{cssxref("border-block-end")}}, que es el borde del final de la dimensión del bloque.

+ +

Puedes ver una comparación entre las propiedades físicas y lógicas a continuación.

+ + + +

Si cambias el modo de escritura de las cajas asignando a la propiedad writing-mode en .box a vertical-rl, vas a ver como las propiedades físicas se quedan ligadas a sus direcciones físicas, mientras que las propiedades lógicas cambian con el modo de escritura.

+ +

También puedes ver que el {{htmlelement("h2")}} tiene  un border-bottom negro. ¿Puedes averiguar como hacer que el borde inferior siempre esté debajo del texto en ambos modos de escritura?

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/logical-mbp.html", '100%', 1200)}}

+ +

Existe un gran número de propiedades cuando consideras cada uno de los bordes que puedes hacer a mano, y puedes ver todas las propiedades asignadas en la página de MDN para propiedades Lógicas y Valores

+ +

Valores lógicos

+ +

Hasta ahora hemos examinado los nombres de las propiedades lógicas. Existen también algunas propiedades que toman valores físicos de top, right, bottom, y left. Estos valores también tienen asignaciones a valores lógicos: block-start, inline-end, block-end, y inline-start.

+ +

Por ejemplo, puedes hacer que una imagen flote a la izquierda para hacer que el texto se ajuste alrededor de la imagen. Puedes reemplazar left con inline-start como se muestra en el ejemplo a continuación.

+ +

Cambia el modo de escritura en este ejemplo a vertical-rl para ver que sucede con la imagen. Cambia inline-start por inline-end para cambiar el modo en que flota.

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/float.html", '100%', 1200)}}

+ +

Aquí también estamos usando valores lógicos de el margen para asegurar que el margen está en el sitio correcto sin importar que modo de escritura es.

+ +
+

Actualmente, solo Firefox soporta valores relativos de flujo para float. Si estás usando Google Chrome Microsoft Edge, deberías ver que la imagen no flota.

+
+ +

¿Debería usar propiedades físicas o lógicas?

+ +

Las propiedades lógicas y los valores son más recientes que su equivalente físico, y por lo tanto se han implementado recientemente en los navegadores. Puedes revisar cualquier página de propiedades en MDN para ver hasta donde llega el soporte del navegador. Si no estás usando multiples modos de escritura, entonces, por ahora, deberías preferir usar las versiones físicas. Sin embargo, en última instancia, esperamos que la gente va a pasar a las versiones lógicas para la mayoría de las cosas, ya que tienen mucho sentido una vez que comienzas a tratar también con métodos de diseño como Flexbox y Grid.

+ +

¡Prueba tus habilidades!

+ +

Tenemos mucho terreno cubierto en este artículo, pero puedes recordad la información más importante? Puedes encontrar algunas pruebas adicionales para verificar que has retenido esta información antes de seguir adelante: Prueba tus habilidades: modos de escritura.

+ +

Resumen

+ +

Los conceptos explicados en esta lección son cada vez más importantes en CSS. Un entendimiento pleno de las direcciones en bloque y en línea, y como el flujo de texto cambia con la variación de los modos de escritura, van a ser de gran ayuda en el futuro. Te ayudará a entender CSS incluso si nunca usas un modo de escritura diferente al horizontal.

+ +

En el módulo siguiente, vamos a echar un buen vistazo al desbordamiento en CSS

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. The box model
  6. +
  7. Backgrounds and borders
  8. +
  9. Handling different text directions
  10. +
  11. Overflowing content
  12. +
  13. Values and units
  14. +
  15. Sizing items in CSS
  16. +
  17. Images, media, and form elements
  18. +
  19. Styling tables
  20. +
  21. Debugging CSS
  22. +
  23. Organizing your CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/selectores_css/combinadores/index.html b/files/es/learn/css/building_blocks/selectores_css/combinadores/index.html new file mode 100644 index 0000000000..54f416456d --- /dev/null +++ b/files/es/learn/css/building_blocks/selectores_css/combinadores/index.html @@ -0,0 +1,111 @@ +--- +title: Combinadores +slug: Learn/CSS/Building_blocks/Selectores_CSS/Combinadores +translation_of: Learn/CSS/Building_blocks/Selectors/Combinators +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

+ +

Los últimos selectores que veremos son los llamados selectores de combinación. Se llaman así porqué combinan otros selectores de manera que proporciona una relación útil entre ellos y la ubicación del contenido en el documento.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con el CSS).
Objetivo:Conocer los diferentes selectores de combinación que se pueden utilizar en el CSS.
+ +

Selector de descendientes

+ +

Ya hemos visto los selectores de descendientes en artículos anteriores (selectores con espacios entre ellos):

+ +
body article p
+ +

Estos selectores seleccionan elementos que son descendientes de otros selectores. No es necesario que sean hijos directos.

+ +

En el ejemplo siguiente seleccionamos solo el elemento <p> que hay dentro de un elemento con una clase .box.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/descendant.html", '100%', 500)}}

+ +

Selector de combinación de elementos hijo

+ +

El selector de combinación de elementos hijo es un símbolo de «mayor que» (>), que selecciona solo cuando los selectores identifican elementos que son hijos directos. Los elementos descendientes que se encuentran más abajo en la jerarquía no se seleccionan. Por ejemplo, para seleccionar solo los elementos <p> que son hijos directos de elementos <article>:

+ +
article > p
+ +

En el ejemplo siguiente hay una lista ordenada anidada dentro de otra lista no ordenada. Utilizamos los selectores de elementos hijo para seleccionar solo los elementos <li> que son hijos directos de <ul> y les aplicamos un borde superior.

+ +

Si eliminamos el símbolo > que lo identifica como un selector de elementos hijo, lo convertimos en un selector de elementos descendientes y se aplicará el borde rojo a todos los elementos <li>.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/child.html", '100%', 600)}}

+ +

Hermanos adyacentes

+ +

El selector de elementos hermanos adyacentes (+) se utiliza para seleccionar un elemento que se encuentra justo al lado de otro elemento en el mismo nivel de la jerarquía. Por ejemplo, para seleccionar todos los elementos <img> que aparecen justo después de elementos <p>:

+ +
p + img
+ +

El caso de uso más común es modificar el párrafo que va justo después del título, como en el ejemplo siguiente. Vamos a buscar un párrafo que sea directamente adyacente a <h1> y le vamos a aplicar un estilo.

+ +

Si insertas algún otro elemento, como <h2> entre las etiquetas <h1> y <p>, verás que el selector ya no selecciona el párrafo y no se muestra con los mismos colores de fondo y de primer plano que cuando es adyacente.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/adjacent.html", '100%', 800)}}

+ +

Hermanos generales

+ +

Si deseas seleccionar los hermanos de un elemento, incluso si no son directamente adyacentes, puedes utilizar el combinador de hermanos general (~). Por ejemplo, para seleccionar todos los elementos <img> que aparecen después de los elementos <p>, hacemos esto:

+ +
p ~ img
+ +

En el ejemplo siguiente seleccionamos todos los elementos <p> que vienen después de <h1>, y aunque en el documento también hay un <div>, se selecciona incluso la etiqueta <p> que viene después.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/general.html", '100%', 600)}}

+ +

El uso de selectores de combinación

+ +

Puedes combinar cualquiera de los selectores de los artículos anteriores con selectores de combinación para seleccionar una parte del documento. Por ejemplo, podrías utilizar el código siguiente para seleccionar elementos de una lista con una clase «a» que son hijos directos de <ul>:

+ +
ul > li[class="a"]  {  }
+ +

Ten cuidado cuando creas largas listas de selectores que seleccionan partes del documento muy específicas. Te será difícil volver a utilizar las reglas CSS porque has definido un selector muy específico para la ubicación del elemento en el marcado.

+ +

A menudo es mejor crear una clase sencilla y aplicarla al elemento en cuestión. Dicho esto, tu conocimiento de los selectores de combinación te será muy útil si necesitas modificar algo del documento y no puedes acceder al código HTML (tal vez porque se haya generado a partir de CMS).

+ +

Comprueba tus habilidades

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más importante? Encontrarás más pruebas para verificar que retienes esa información en Test your skills: Selectors.

+ +

Continuamos

+ +

Esta es la última sección de nuestros artículos sobre selectores. A continuación vamos a pasar a otra parte importante del CSS: el modelo de caja CSS.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks/The_box_model", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Elementos de imagen, de media y de formulario
  18. +
  19. Estilo de las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/selectores_css/index.html b/files/es/learn/css/building_blocks/selectores_css/index.html new file mode 100644 index 0000000000..d0ea61da20 --- /dev/null +++ b/files/es/learn/css/building_blocks/selectores_css/index.html @@ -0,0 +1,223 @@ +--- +title: Selectores CSS +slug: Learn/CSS/Building_blocks/Selectores_CSS +translation_of: Learn/CSS/Building_blocks/Selectors +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}
+ +

En {{Glossary( "CSS")}} los selectores se utilizan para delimitar los elementos {{glossary("HTML")}} de nuestra página web a los que queremos aplicar estilo. Hay una amplia variedad de selectores CSS, lo que permite una gran precisión a la hora de seleccionar elementos a los que aplicar estilo. En este artículo y sus subartículos veremos con detalle todos los tipos y el modo como funcionan.

+ + + + + + + + + + + + +
Prerrequisitos:Nociones básicas de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, conocimientos básicos de HTML (véase Introducción a HTML) y una idea de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Aprender con detalle cómo funcionan los selectores CSS.
+ +

¿Qué es un selector?

+ +

En un artículo anterior explicamos qué son los selectores. Un selector CSS es la primera parte de una regla CSS. Es un patrón de elementos y otros términos que indican al navegador qué elementos HTML se seleccionan para aplicarles una regla que incluye los valores de las propiedades CSS. El elemento o los elementos seleccionados por el selector se denominan sujeto del selector.

+ +

Fragmento de código con el elemento h1 resaltado.

+ +

En artículos anteriores ya has visto algunos selectores y has aprendido que hay diversas maneras de organizar el documento. Por ejemplo, seleccionando un elemento, como h1, o seleccionando una clase, como .special.

+ +

En CSS, los selectores se definen en la especificación de selectores de CSS correspondiente; al igual que cualquier otro elemento de CSS, es necesario que los navegadores los admitan para que funcionen. La mayoría de los selectores que encontrarás se definen en especificación de nivel 3 de selectores, que es una especificación consolidada y, por lo tanto, la mayoría de navegadores admitirán esos selectores.

+ +

Listas de selectores

+ +

Si más de un elemento utiliza el mismo CSS, puedes combinar los selectores en una lista de selectores para que la regla se aplique a cada uno de los selectores individuales. Por ejemplo, si tengo el mismo CSS para un h1 y para una clase .special, los puedo escribir como dos reglas separadas.

+ +
h1 {
+  color: blue;
+}
+
+.special {
+  color: blue;
+} 
+ +

También los podrías combinar en una lista de selectores, separándolos con una coma.

+ +
h1, .special {
+  color: blue;
+} 
+ +

Es posible dejar un espacio en blanco tanto antes como después de la coma. Incluso puede resultar más legible si cada selector se encuentra en una línea distinta.

+ +
h1,
+.special {
+  color: blue;
+} 
+ +

En el ejemplo siguiente, intenta combinar los dos selectores de modo que tengan la misma declaración. El aspecto visual debe permanecer igual tras la combinación.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/selector-list.html", '100%', 1000)}} 

+ +

Cuando agrupas los selectores de esta manera, si alguno de los selectores no es válido, el navegador sencillamente ignora toda la regla.

+ +

En el ejemplo siguiente, la regla que corresponde al selector de clase que no es válido se ignora, mientras que el estilo se aplica al elemento h1.

+ +
h1 {
+  color: blue;
+}
+
+..special {
+  color: blue;
+} 
+ +

Sin embargo, si se combinan, toda la regla se considera no válida y no se aplicará estilo ni a h1 ni a la clase.

+ +
h1, ..special {
+  color: blue;
+} 
+ +

Tipos de selectores

+ +

Hay diferentes agrupaciones de selectores, y conocer qué tipo de selector necesitas te ayudará a encontrar la herramienta adecuada para tu trabajo. En estos subartículos vamos a ver los diferentes grupos de selectores con más detalle.

+ +

Selectores de tipo, de clase y de ID

+ +

Este grupo incluye selectores que delimitan un elemento HTML, como por ejemplo un <h1>.

+ +
h1 { }
+ +

También incluye selectores que delimitan una clase:

+ +
.box { }
+ +

o un ID:

+ +
#unique { }
+ +

Selectores de atributo

+ +

Este grupo de selectores te proporciona diferentes formas de seleccionar elementos según la presencia de un atributo determinado en un elemento:

+ +
a[title] { }
+ +

O incluso hacer una selección basada en la presencia de un atributo que tiene un valor particular asignado:

+ +
a[href="https://example.com"] { }
+ +

Las pseudoclases y los pseudoelementos

+ +

Este grupo de selectores incluye pseudoclases, que aplican estilo a ciertos estados de un elemento. La pseudoclase :hover, por ejemplo, selecciona un elemento solo cuando se le pasa el ratón por encima.

+ +
a: hover {}
+ +

También incluye pseudoelementos, que seleccionan una parte determinada de un elemento en vez del elemento en sí. Por ejemplo, ::first-line siempre selecciona la primera línea del texto que se encuentra dentro de un elemento (<p>, en el ejemplo siguiente), y actúa como si un elemento <span> hubiera delimitado la primera línea, seleccionado y aplicado estilo.

+ +
p::first-line { }
+ +

Combinadores

+ +

El último grupo de selectores combina otros selectores con el fin de delimitar elementos de nuestros documentos. El ejemplo siguiente selecciona los párrafos que son hijos directos del elemento <article> utilizando el operador de combinación hijo (>):

+ +
article > p { }
+ +

Próximos pasos

+ +

Echa un vistazo a esta tabla de referencia de selectores que contiene enlaces directos a los distintos tipos de selectores que se explican en nuestra sección de aprendizaje o en MDN, o bien sigue adelante e inicia tu viaje para averiguar cómo funcionan en Selectores de tipo, de clase y de ID.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Cascade_and_inheritance", "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks")}}

+ +

Tabla de referencia de selectores

+ +

La tabla que te mostramos a continuación proporciona una descripción general de los selectores que puedes utilizar junto con enlaces a diversas páginas de esta guía que te mostrarán cómo utilizar cada tipo de selector. También hemos incluido un enlace a la página MDN de cada selector para poder comprobar la información sobre los navegadores que lo admiten. Puedes utilizarlo como referencia para volver cuando necesites buscar los selectores a medida que avanzas con la materia o mientras experimentas con CSS por tu cuenta.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorEjemploTutorial de aprendizaje de CSS
Selector de tipoh1 {  }Los tipos de selectores
Selector universal* {  }El selector universal
Selector de clase.box {  }Los selectores de clase
Selector de ID#unique { }Los selectores de ID
Selector de atributoa[title] {  }Los selectores de atributo
Pseudoclasep:first-child { }Las pseudoclases
Pseudoelementop::first-line { }Los pseudoelementos
Operadores de combinación descendentesarticle pOperadores de combinación descendentes
Operador de combinación de elementos hijoarticle > pOperadores de combinación de elementos hijo
Operador de combinación de elementos hermanos adyacentesh1 + pHermanos adyacentes
Operador de combinación general de elementos hermanosh1 ~ pHermanos generales
+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/selectores_css/pseudo-clases_y_pseudo-elementos/index.html b/files/es/learn/css/building_blocks/selectores_css/pseudo-clases_y_pseudo-elementos/index.html new file mode 100644 index 0000000000..f48dfdcbd5 --- /dev/null +++ b/files/es/learn/css/building_blocks/selectores_css/pseudo-clases_y_pseudo-elementos/index.html @@ -0,0 +1,397 @@ +--- +title: Pseudoclases y pseudoelementos +slug: Learn/CSS/Building_blocks/Selectores_CSS/Pseudo-clases_y_pseudo-elementos +translation_of: Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

+ +

El conjunto de selectores que estudiaremos en este artículo se conocen como pseudoclases y pseudoelementos. Hay muchos y a menudo sirven para fines muy específicos. Una vez que sepas cómo usarlos, puedes echar un vistazo a la lista para ver si alguno sirve para la página que quieres crear. Una vez más, la página correspondiente de MDN resulta muy útil para conocer qué navegadores los admiten o no.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con el CSS).
Objetivo:Obtener información sobre los selectores de pseudoclases y pseudoelementos.
+ +

¿Qué es una pseudoclase?

+ +

Una pseudoclase es un selector que marca los elementos que están en un estado específico, por ejemplo, los que son el primer elemento de su tipo, o aquellos por los que el cursor les pasa por encima. Tienden a actuar como si hubieras aplicado una clase en una parte determinada del documento y, a menudo, ayudan a reducir el exceso de clases y proporcionan un marcado más flexible y fácil de mantener.

+ +

Las pseudoclases son palabras clave que comienzan con dos puntos:

+ +
:pseudo-class-name
+ +

Ejemplos simples de pseudoclases

+ +

Echemos un vistazo a algunos ejemplos. Si queremos el primer párrafo de un artículo en letra más grande y en negrita, podemos añadir una clase a ese párrafo y luego añadirle CSS a esa clase, como se muestra en este ejemplo:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child.html", '100%', 800)}}

+ +

Sin embargo, podría ser complicado de mantener. ¿Y si añadiésemos un párrafo nuevo en la parte superior del documento? Habría que mover la clase para que quede antes del nuevo párrafo. En lugar de añadir la clase, podríamos utilizar el selector de pseudoclase {{cssxref(":first-child")}}, que siempre seleccionará el primer elemento hijo del artículo, y de esta forma no tendremos que editar el código HTML (esto no siempre es posible, tal vez debido a que lo genera un CMS).

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-child2.html", '100%', 700)}}

+ +

Todas las pseudoclases se comportan del mismo modo. Seleccionan un fragmento del documento que está en un estado determinado y se comportan como si se hubiera añadido una clase a su HTML. Echa un vistazo a otros ejemplos en MDN:

+ + + +
+

Nota: Es válido escribir pseudoclases y pseudoelementos sin que les preceda un selector de elemento. En el ejemplo anterior, podría escribirse :first-child y la regla se aplicaríaa cualquier elemento que sea el primer hijo de un elemento <article>, no solo un párrafo primer hijo. :first-child equivale a *:first-child. Pero normalmente se quiere más control y hay que ser más específico.

+
+ +

Pseudoclases de acción de usuario

+ +

Algunas pseudoclases solo intervienen cuando el usuario interactúa con el documento de alguna manera. Estas pseudoclases de acción de usuario, que también reciben el nombre de pseudoclases dinámicas, actúan como si se añadiese una clase al elemento cuando el usuario interactúa con él. Algunos ejemplos son:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/hover.html", '100%', 500)}}

+ +

¿Qué es un pseudoelemento?

+ +

Los pseudoelementos se comportan de manera similar. Sin embargo, actúan como si hubieras añadido un elemento HTML totalmente nuevo en el marcado, en lugar de haber aplicado una clase nueva a los elementos presentes. Los pseudoelementos empiezan con un doble signo de dos puntos ::.

+ +
::pseudo-element-name
+ +
+

Nota: Algunos de los primeros pseudoelementos utilizaban la sintaxis de un solo signo de dos puntos, así que puede ser que en ocasiones los veas escritos de esta forma en algún código o ejemplo. Los navegadores modernos leen tanto los pseudoelementos con la sintaxis de los dos puntos simple como la de los dos puntos doble para garantizar la compatibilidad retrospectiva.

+
+ +

Por ejemplo, si deseas seleccionar la primera línea de un párrafo simplemente puedes delimitarlo con el elemento <span> y utilizar un selector de elementos. Sin embargo, fallará si el número de palabras que has delimitado resulta ser más largo o más corto que el ancho del elemento padre. Ya que normalmente no sabemos cuántas palabras caben en una línea porque esto cambia con el ancho de la pantalla o con los cambios de tamaño de la letra, no es posible hacer esto introduciendo solo HTML.

+ +

El pseudoelemento ::first-line soluciona este problema: no importa si el número de palabras aumenta o disminuye, siempre se selecciona la primera línea.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/first-line.html", '100%', 800)}}

+ +

Actúa como si hubiera un elemento <span> mágicamente delimitando esa primera línea, que se actualiza cada vez que la longitud de la línea cambia.

+ +

Puedes observar que en ambos párrafos se selecciona la primera línea.

+ +

Combinar pseudoclases y pseudoelementos

+ +

Si quieres poner en negrita la primera línea del primer párrafo, puedes encadenar los selectores :first-child y ::first-line. Añade al ejemplo anterior el CSS siguiente. Queremos que se seleccione la primera línea del primer elemento <p> que esté dentro de un elemento <article>.

+ +
article p:first-child::first-line {
+  font-size: 120%;
+  font-weight: bold;
+}
+ +

Generar contenido con ::before y ::after

+ +

Hay un par de pseudoelementos especiales que se utilizan junto con la propiedad de content para introducir contenido en el documento usando el CSS.

+ +

Puedes utilizarlos para insertar una cadena de texto, como en el ejemplo siguiente. Intenta cambiar el valor del texto de la propiedad {{cssxref("content")}} y observa el cambio en la salida. También puedes cambiar el pseudoelemento ::before por ::after y verás que el texto se inserta al final del elemento, en lugar de al principio.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/before.html", '100%', 400)}}

+ +

Sin embargo, en realidad no es habitual insertar cadenas de texto desde el CSS, porque ese texto resulta inaccesible para algunos lectores de pantalla y puede ser difícil de buscar y modificar en el futuro.

+ +

Un uso más adecuado de estos pseudoelementos es insertar un icono. Por ejemplo, la pequeña flecha que añadimos en el ejemplo siguiente es un indicador visual que no queremos que el lector de pantalla muestre:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/after-icon.html", '100%', 400)}}

+ +

Estos pseudoelementos también se utilizan con frecuencia para insertar una cadena vacía a la que luego se le puede aplicar estilo, como a cualquier otro elemento de la página.

+ +

En el ejemplo siguiente hemos añadido una cadena vacía mediante el pseudoelemento ::before. Le hemos asociado display: block para poder aplicarle estilo para que tenga una anchura y una altura determinadas. A continuación, utilizamos el CSS para aplicar estilo de la misma forma que lo haríamos con cualquier otro elemento. Juega con el CSS y cambia la forma en que se ve y se comporta.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/before-styled.html", '100%', 500)}}

+ +

El uso de los pseudoelementos ::before y ::after, junto con la propiedad content se conoce como «contenido generado» en CSS, y verás que esta técnica se utiliza a menudo para diversas tareas. Un buen ejemplo es la página web CSS Arrow Please, que te ayuda a generar una flecha con CSS. Echa un vistazo al CSS a medida que creas tu flecha y verás cómo funcionan los pseudoelementos {{cssxref("::before")}} y {{cssxref("::after")}}. Cada vez que veas estos selectores, echa un vistazo a la propiedad {{cssxref("content")}} para ver qué se añade al documento.

+ +

Sección de referencia

+ +

Hay un gran número de pseudoclases y pseudoelementos, así que resulta útil tener una lista para ir consultándolos. A continuación encontrarás un par de tablas con enlaces a sus páginas de referencia en MDN. Tómalas como referencia para ver de qué dispones para seleccionar qué tipos de elementos.

+ +

Las pseudoclases

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorDescripción
{{ Cssxref(":active") }}Selecciona un elemento cuando el usuario lo activa (por ejemplo, con un clic).
{{ Cssxref(":any-link") }}Selecciona los estados :link y :visited de un enlace.
{{ Cssxref(":blank") }}Selecciona un elemento <input> cuyo valor de entrada está vacío.
{{ Cssxref(":checked") }}Selecciona un botón de opción o casilla de verificación en el estado que determines.
{{ Cssxref(":current") }}Selecciona el elemento que se muestra en ese momento, o un ancestro de ese elemento.
{{ Cssxref(":default") }}Selecciona uno o más elementos de interfaz de usuario cuyo valor es el predeterminado de entre un conjunto de elementos similares.
{{ Cssxref(":dir") }}Selecciona un elemento según su direccionalidad (valor del atributo dir de HTML o propiedad direction de CSS).
{{ Cssxref(":disabled") }}Selecciona elementos de la interfaz de usuario que están en estado inactivo.
{{ Cssxref(":empty") }}Selecciona un elemento que no tiene elementos hijo, excepto por algún espacio en blanco opcional.
{{ Cssxref(":enabled") }}Selecciona elementos de la interfaz de usuario que están en estado activo.
{{ Cssxref(":first") }}En Paged Media, selecciona la primera página.
{{ Cssxref(":first-child") }}Selecciona el primero entre elementos hermanos.
{{ Cssxref(":first-of-type") }}Selecciona el primero entre un tipo determinado de elementos hermanos.
{{ Cssxref(":focus") }}Selecciona el elemento que tiene el foco.
{{ Cssxref(":focus-visible")}}Selecciona el elemento que tiene el foco cuando el foco tiene que estar visible para el usuario.
{{ Cssxref(":focus-within") }}Selecciona el elemento que tiene el foco y el elemento con un descendiente que tiene el foco.
{{ Cssxref(":future") }}Selecciona los elementos que van después del elemento en curso.
{{ Cssxref(":hover") }}Selecciona un elemento cuando el usuario interactúa con él.
{{ Cssxref(":indeterminate") }}Selecciona elementos de interfaz de usuario cuyo valor está en un estado no determinado, por lo general se trata de casillas de verificación.
{{ Cssxref(":in-range") }}Selecciona un elemento cuyo valor se encuentra dentro de un rango de valores determinado.
{{ Cssxref(":invalid") }}Selecciona un elemento, como por ejemplo un <input>, cuyo estado es no válido.
{{ Cssxref(":lang") }}Selecciona un elemento según el idioma (valor del atributo lang de HTML).
{{ Cssxref(":last-child") }}Selecciona el último elemento de entre sus elementos hermanos.
{{ Cssxref(":last-of-type") }}Selecciona el último de entre los elementos hermanos de un tipo determinado.
{{ Cssxref(":left") }}En Paged Media selecciona las páginas de la izquierda.
{{ Cssxref(":link")}}Selecciona los enlaces no visitados.
{{ Cssxref(":local-link")}}Selecciona los enlaces que dirigen a páginas que se encuentran en la misma página web que el documento activo.
{{ Cssxref(":is", ":is()")}}Selecciona cualquiera de los selectores de la lista de selección que se pase como valor de este selector.
{{ Cssxref(":not") }}Selecciona elementos que otros selectores no han seleccionado antes y que se han pasado como valor de este selector.
{{ Cssxref(":nth-child") }}Selecciona elementos de entre una lista de elementos hermanos. Los elementos hermanos están relacionados por una fórmula del tipo an + b (por ejemplo, 2n + 1 seleccionaría los elementos 1, 3, 5, 7, etc., es decir, todos los impares).
{{ Cssxref(":nth-of-type") }}Selecciona elementos de entre una lista de elementos hermanos de un tipo determinado (por ejemplo, todos los elementos <p>). Los elementos hermanos están relacionados por una fórmula del tipo an + b (por ejemplo, 2n + 1 relacionaría en la secuencia ese tipo de elementos, los números 1, 3, 5, 7, etc., es decir, todos los impares).
{{ Cssxref(":nth-last-child") }}Selecciona elementos de entre una lista de elementos hermanos, contando hacia atrás desde el final. Los elementos hermanos están relacionados por una fórmula del tipo an+b (por ejemplo, 2n + 1 relacionaría en la secuencia el último de los elementos de este tipo con el que se encuentra dos por delante, y así sucesivamente. Todos los impares, contando desde el final).
{{ Cssxref(":nth-last-of-type") }}Selecciona los elementos de entre una lista de elementos hermanos que son de un tipo determinado (por ejemplo, elementos <p>), contando hacia atrás desde el final. Los elementos hermanos están relacionados por una fórmula del tipo an+b (por ejemplo, 2n + 1 relacionaría en la secuencia el último de los elementos de ese tipo con el que se encuentra dos por delante, y así sucesivamente. Todos los impares, contando desde el final).
{{ Cssxref(":only-child") }}Selecciona un elemento que no tiene elementos hermanos.
{{ Cssxref(":only-of-type") }}Selecciona un elemento que es el único de su tipo entre sus elementos hermanos.
{{ Cssxref(":optional") }}Selecciona los elementos de formulario que son innecesarios.
{{ Cssxref(":out-of-range") }}Selecciona un elemento cuyo valor está fuera de rango.
{{ Cssxref(":past") }}Selecciona los elementos que se encuentran antes del elemento activo.
{{ Cssxref(":placeholder-shown") }}Selecciona el elemento de entrada que muestra texto de marcador de posición.
{{ Cssxref(":playing") }}Selecciona un elemento que representa un audio, un vídeo o un recurso similar que se puede «reproducir» o «pausar», cuando el elemento está «en reproducción».
{{ Cssxref(":paused") }}Selecciona un elemento que representa un audio, un vídeo o un recurso similar que se puede “«reproducir» o «pausar» cuando el elemento está «pausado».
{{ Cssxref(":read-only") }}Selecciona los elementos que el usuario no puede modificar.
{{ Cssxref(":read-write") }}Selecciona los elementos que el usuario puede modificar.
{{ Cssxref(":required") }}Selecciona los elementos de formulario que son necesarios.
{{ Cssxref(":right") }}En Paged Media selecciona las páginas de la derecha.
{{ Cssxref(":root") }}Selecciona un elemento que es la raíz del documento.
{{ Cssxref(":scope") }}Selecciona cualquier elemento de ámbito.
{{ Cssxref(":valid") }}Selecciona un elemento como <input>, en un estado válido.
{{ Cssxref(":target") }}Selecciona el elemento al que apunta la URL activa (es decir, cuyo ID coincide con el identificador de fragmento de la URL activo).
{{ Cssxref(":visited") }}Selecciona los enlaces visitados.
+ +

Pseudoelementos

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorDescripción
{{ Cssxref("::after") }}Selecciona el elemento al que se puede aplicar estilo que aparece a continuación del contenido del elemento que lo origina.
{{ Cssxref("::before") }}Selecciona el elemento al que se puede aplicar estilo que aparece antes del contenido del elemento que lo origina.
{{ Cssxref("::first-letter") }}Selecciona la primera letra del elemento.
{{ Cssxref("::first-line") }}Selecciona la primera línea del elemento de contenido.
{{ Cssxref("::grammar-error") }}Selecciona una parte del documento que contiene un error de gramática indicado por el navegador.
{{ Cssxref("::selection") }}Selecciona la parte del documento que ha sido seleccionada.
{{ Cssxref("::spelling-error") }}Selecciona una parte del documento que contiene un error de ortografía indicado por el navegador.
+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks/Selectors/Combinators", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Elementos de imagen, de media y de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/selectores_css/selectores_de_atributos/index.html b/files/es/learn/css/building_blocks/selectores_css/selectores_de_atributos/index.html new file mode 100644 index 0000000000..057c38c18d --- /dev/null +++ b/files/es/learn/css/building_blocks/selectores_css/selectores_de_atributos/index.html @@ -0,0 +1,154 @@ +--- +title: Selectores de atributo +slug: Learn/CSS/Building_blocks/Selectores_CSS/Selectores_de_atributos +translation_of: Learn/CSS/Building_blocks/Selectors/Attribute_selectors +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

+ +

Como ya explicamos en los artículos de HTML, los elementos pueden tener atributos que proporcionan un nivel de detalle mayor sobre el elemento que delimitan. En el CSS puedes utilizar selectores de atributo para seleccionar elementos definidos con unos atributos determinados. En este artículo veremos cómo utilizar estos selectores tan útiles.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Aprender a identificar y utilizar selectores de atributo.
+ +

Selectores de presencia y valor

+ +

Estos selectores permiten seleccionar un elemento solo a partir de la presencia de un atributo (por ejemplo href) o a partir de varias coincidencias diferentes con respecto al valor del atributo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorEjemploDescripción
[attr]a[title]Relaciona elementos con un mismo nombre de atributo, attr (el valor que se indica entre corchetes).
[attr=value]a[href="https://example.com"]Relaciona elementos con un mismo nombre de atributo, attr, cuyo valor es exactamente el mismo, value (la cadena de caracteres que se indica entre corchetes).
[attr~=value]p[class~="special"] +

Relaciona los elementos con un mismo nombre de atributo, attr, cuyo valor es exactamente value, o los elementos con un mismo atributo attr que contiene uno o más valores de los cuales, al menos uno, coincide con value.

+ +

Ten en cuenta que en una lista que incluya más de un valor, los distintos valores se separan con un espacio.

+
[attr|=value]div[lang|="zh"]Relaciona los elementos con un mismo nombre de atributo, attr, cuyo valor puede ser exactamente value o puede comenzar con value seguido inmediatamente por un guion.
+ +

En el ejemplo siguiente puedes observar cómo se utilizan estos selectores.

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute.html", '100%', 800)}}

+ +

Selectores coincidentes con subcadenas

+ +

Estos selectores permiten un tipo más avanzado de relación entre las subcadenas de caracteres que constituyen el valor del atributo. Por ejemplo, si tienes las clases box-warning y box-error y quieres encontrar todos los elementos que empiezan con la cadena de caracteres “box-”, puedes seleccionarlas ambas con [class^="box-"].

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorEjemploDescripción
[attr^=value]li[class^="box-"]Relaciona elementos con un mismo nombre de atributo, attr, cuyo valor empieza exactamente con la subcadena de caracteres value.
[attr$=value]li[class$="-box"]Relaciona elementos con un mismo nombre de atributo, attr, cuyo valor termina exactamente con la subcadena de caracteres value.
[attr*= ]li[class*="box"]Relaciona elementos con un mismo nombre de atributo, attr, cuyo valor incluye al menos una ocurrencia de la subcadena value en algún punto de la cadena.
+ +

El ejemplo siguiente muestra cómo se usan estos selectores:

+ + + +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-substring.html", '100%', 800)}}

+ +

Mayúsculas y minúsculas

+ +

Si quieres relacionar los valores de atributo tanto si están escritos en mayúsculas como en minúsculas, puedes utilizar el valor i antes del paréntesis de cierre. Este indicador informa al navegador de que debe relacionar todos los caracteres ASCII independientemente de si las letras son mayúsculas o minúsculas. Sin este indicador, los valores se relacionarán según las directrices del lenguaje del documento con respecto a la distinción entre mayúsculas y minúsculas; en el caso del HTML, se distinguirá entre mayúsculas y minúsculas.

+ +

En el ejemplo siguiente, el primer selector relaciona valores que empiezan con a; luego, solo coincide el primer elemento de la lista porque los otros dos comienzan con una A mayúscula. El segundo selector utiliza el indicador de no distinción entre mayúsculas y minúsculas, así que relaciona todos los elementos de la lista.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/attribute-case.html", '100%', 800)}}

+ +
+

Nota: Recientemente se ha creado un valor s, que obliga a establecer la distinción de mayúsculas y minúsculas en contextos en que no se suele establecer esta distinción. Sin embargo, pocos navegadores lo utilizan y no resulta demasiado útil en un contexto HTML.

+
+ +

Próximos pasos

+ +

Ahora que hemos terminado con los selectores de atributo, puedes avanzar al artículo siguiente y leer acerca de los selectores de pseudoclases y pseudoelementos.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors", "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/selectores_css/selectores_de_tipo_clase_e_id/index.html b/files/es/learn/css/building_blocks/selectores_css/selectores_de_tipo_clase_e_id/index.html new file mode 100644 index 0000000000..01b3963f8a --- /dev/null +++ b/files/es/learn/css/building_blocks/selectores_css/selectores_de_tipo_clase_e_id/index.html @@ -0,0 +1,117 @@ +--- +title: 'Selectores de tipo, clase e ID' +slug: Learn/CSS/Building_blocks/Selectores_CSS/Selectores_de_tipo_clase_e_ID +translation_of: Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors +--- +

{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

+ +

En este artículo vamos a echar un vistazo a los selectores más simples de que dispones y que seguramente serán los que utilices con mayor frecuencia.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con CSS).
Objetivo:Conocer los diferentes selectores CSS que podemos utilizar para aplicar CSS a un documento.
+ +

Tipos de selectores

+ +

Un selector de tipo también recibe el nombre de selector de nombre de etiqueta o selector de elemento porque selecciona un elemento/etiqueta HTML del documento. En el ejemplo siguiente hemos utilizado los selectores span, em y strong. Se aplica estilo a todas las instancias de los elementos <span>, <em> y <strong>.

+ +

Trata de añadir una regla CSS que seleccione el elemento <h1> y cambie su color para que se vea azul.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/type.html", '100%', 1100)}}

+ +

El selector universal

+ +

El selector universal se indica con un asterisco (*) y selecciona todos los elementos del documento (o del elemento padre si está encadenado con otro elemento y un operador de combinación descendente, por ejemplo). En el ejemplo siguiente hemos utilizado el selector universal para eliminar los márgenes en todos los elementos. Esto significa que en lugar de la opción predeterminada de aplicación de estilos del navegador, que muestra los títulos de encabezado y los párrafos separados por un margen de respeto, todo se mostrará pegado y no resultará tan fácil distinguir los diversos párrafos.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/universal.html", '100%', 750)}}

+ +

Es posible observar este tipo de comportamiento en las «hojas de estilo de puesta a cero» (o «hojas de estilo reset»), que anulan el formato del navegador. Fueron muy populares en un momento dado; sin embargo, excluir todo el estilo significa que luego tienes que ponerlo todo de nuevo. Por este motivo tendemos a utilizar el selector universal con mucho cuidado, y para situaciones muy específicas como la que se describe a continuación.

+ +

Uso del selector universal para facilitar la legibilidad de tus selectores

+ +

Uno de los usos del selector universal es facilitar la legibilidad de los selectores y clarificar sus funciones. Por ejemplo, si quiero seleccionar el primer elemento hijo de cualquier elemento <article> y poner ese elemento, cualquiera que sea, en negrita, puedo utilizar el selector {{cssxref(":first-child")}}, que veremos con mayor detalle más adelante en el artículo de pseudoclases y pseudoelementos, como selector descendente junto con el selector de elemento <article>

+ +
article :first-child {
+
+}
+ +

Sin embargo, esto podría confundirse con article:first-child, que selecciona cualquier elemento <article> que sea el primer elemento hijo de otro elemento.

+ +

Para evitar esta confusión podemos añadir al selector :first-child el selector universal. De este modo la función del selector resulta obvia: seleccionará cualquier elemento que entre en la jerarquía de primer hijo de un elemento <article>:

+ +
article *:first-child {
+
+} 
+ +

Selectores de clase

+ +

El selector de clase comienza con un punto (.) y selecciona todo elemento del documento que esté afectado por esa clase. En el ejemplo siguiente hemos creado una clase llamada .highlight y la hemos aplicado en varios lugares del documento. Todos los elementos a los que se aplique esta clase se resaltarán en amarillo.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class.html", '100%', 750)}}

+ +

Delimitación de clases en elementos particulares

+ +

Puedes crear un selector que seleccionará los elementos concretos que estén afectados por esa clase. En el ejemplo siguiente vamos a introducir un resaltado en un elemento <span> con una clase highlight del de los títulos <h1> con clase highlight. Para ello hay que anexar esa clase al selector de tipo correspondiente al elemento que queremos delimitar, sin dejar entre ellos ningún espacio.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class-type.html", '100%', 750)}}

+ +

Este enfoque hace el elemento CSS menos reutilizable porque la clase solo se aplicará a ese elemento en particular y tendrás que agregar otro selector en caso que quieras que las normas también se apliquen a otros elementos.

+ +

Delimitar un elemento afectado por más de una clase

+ +

Puedes aplicar más de una clase a un elemento y delimitarlos de forma individual o seleccionar el elemento cuando todas las clases están presentes en el selector. Puede ser útil cuando se trabaja con componentes que se pueden combinar de maneras diferentes en tu página web.

+ +

En el ejemplo siguiente hay un elemento <div> que contiene una nota. El borde gris se aplica cuando la caja tiene una clase notebox. Si además tiene una clase warning o danger, la propiedad {{cssxref("border-color")}} cambia.

+ +

Para decirle al navegador que solo queremos seleccionar el elemento si incluye todas estas clases, las encadenamos juntas sin ningún espacio entre ellas.

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/class-many.html", '100%', 900)}}

+ +

Selectores de ID

+ +

Un selector de ID comienza con un carácter # en lugar de un punto, pero se utiliza básicamente de la misma manera que un selector de clase. Sin embargo, un ID se puede utilizar una sola vez en cada documento, y a cada elemento solo se le puede aplicar un único id. Puede seleccionar un elemento que tenga propiedad id y ese ID puede ir precedido de un selector de tipo que seleccionará el elemento solo si el elemento y el ID coinciden. En el ejemplo siguiente puedes ver todos estos usos:

+ +

{{EmbedGHLiveSample("css-examples/learn/selectors/id.html", '100%', 750)}}

+ +
+

Nota: Como aprendimos en el artículo sobre la especificidad, un ID tiene una especificidad muy alta y anula la mayoría de los otros selectores. Esto puede dificultar su uso. En la mayoría de los casos es preferible añadir una clase al elemento en lugar de utilizar un ID. Sin embargo, si el ID es la única manera de seleccionar el elemento (tal vez porque no tengas acceso al marcado y, por lo tanto, no lo puedes editar) no hay ningún problema en utilizarlo.

+
+ +

En el próximo artículo

+ +

Seguiremos con la descripción de los selectores examinando los selectores de atributo.

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Selectors", "Learn/CSS/Building_blocks/Selectors/Attribute_selectors", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. La cascada y la herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git a/files/es/learn/css/building_blocks/styling_tables/index.html b/files/es/learn/css/building_blocks/styling_tables/index.html new file mode 100644 index 0000000000..283df180e4 --- /dev/null +++ b/files/es/learn/css/building_blocks/styling_tables/index.html @@ -0,0 +1,282 @@ +--- +title: Estilizando tablas +slug: Learn/CSS/Building_blocks/Styling_tables +translation_of: Learn/CSS/Building_blocks/Styling_tables +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_boxes/Borders", "Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes")}}
+ +

Aplicar estilos a una tabla HTML no es el trabajo más interesante del mundo, pero a veces hay que hacerlo. Este artículo proporciona una guía para hacer que las tablas HTML presenten un aspecto agradable, para ello usaremos algunas de las características específicas para tablas que hemos destacado en artículos anteriores.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de HTML (véase Introducción a HTML) y tablas HTML, y nociones de cómo funciona el CSS (véase Introducción al CSS.)
Objetivo:Aprender a aplicar estilo a tablas HTML de una forma efectiva.
+ +

Una tabla HTML típica

+ +

Comencemos por echar un vistazo a una tabla HTML típica. Bueno, decimos típica porque la mayoría de los ejemplos de tablas HTML son sobre zapatos, el tiempo o empleados; y hemos decidido hacer las cosas más interesantes creando una tabla sobre grupos de música punk famosos del Reino Unido. El código es el siguiente:

+ +
<table summary="Los grupos de música punk más famosos del Reino Unido">
+  <caption>Un resumen de los grupos de música punk más famosos del Reino Unido</caption>
+  <thead>
+    <tr>
+      <th scope="col">Grupo</th>
+      <th scope="col">Año de formación</th>
+      <th scope="col">Número de álbumes</th>
+      <th scope="col">Canción más conocida</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th scope="row">Buzzcocks</th>
+      <td>1976</td>
+      <td>9</td>
+      <td>Ever fallen in love (with someone you shouldn't've)</td>
+    </tr>
+    <tr>
+      <th scope="row">The Clash</th>
+      <td>1976</td>
+      <td>6</td>
+      <td>London Calling</td>
+    </tr>
+
+      ... se han eliminado algunas filas por abreviar
+
+    <tr>
+      <th scope="row">The Stranglers</th>
+      <td>1974</td>
+      <td>17</td>
+      <td>No More Heroes</td>
+    </tr>
+  </tbody>
+  <tfoot>
+    <tr>
+      <th scope="row" colspan="2">Número total de álbumes</th>
+      <td colspan="2">77</td>
+    </tr>
+  </tfoot>
+</table>
+ +

La tabla está bien creada, puede aplicársele estilo fácilmente y presenta características de accesibilidad gracias a propiedades como {{htmlattrxref("scope","th")}}, {{htmlelement("caption")}}, {{htmlattrxref("summary","table")}}, {{htmlelement("thead")}}, {{htmlelement("tbody")}}, etc. Por desgracia, no presenta un aspecto agradable cuando se muestra en pantalla (puedes ver el ejemplo en punk-bands-unstyled.html):

+ +

+ +

Tal y como está, es aburrida y difícil de leer. Necesitamos usar algo de CSS para arreglar esto.

+ +

Aprendizaje activo: Aplicar estilo a nuestra tabla

+ +

En esta sección de aprendizaje activo vamos a aplica estilo a nuestra tabla juntos.

+ +
    +
  1. Para comenzar, crea una copia local del código de ejemplo, descarga las dos imágenes (noise y leopardskin), y pon los tres archivos en alguna carpeta de tu ordenador.
  2. +
  3. Ahora crea un archivo nuevo llamado style.css y guárdalo con el resto de archivos, en la misma carpeta.
  4. +
  5. Enlaza el CSS al HTML copiando la línea siguiente en {{htmlelement("head")}}: +
    <link href="style.css" rel="stylesheet" type="text/css">
    +
  6. +
+ +

Espaciado y distribución

+ +

Lo primero que hay que hacer es solucionar los aspectos de espaciado/distribución; ¡el estilo por defecto de la tabla es tan apretado! Para ello, añadimos el CSS siguiente al archivo style.css:

+ +
/* spacing */
+
+table {
+  table-layout: fixed;
+  width: 100%;
+  border-collapse: collapse;
+  border: 3px solid purple;
+}
+
+thead th:nth-child(1) {
+  width: 30%;
+}
+
+thead th:nth-child(2) {
+  width: 20%;
+}
+
+thead th:nth-child(3) {
+  width: 15%;
+}
+
+thead th:nth-child(4) {
+  width: 35%;
+}
+
+th, td {
+  padding: 20px;
+}
+ +

Las partes más importantes que destacamos son:

+ + + +

En este punto, nuestra tabla ya presenta un aspecto mucho más agradable:

+ +

+ +

Un poco de tipografía

+ +

Ahora arreglaremos un poco nuestro texto.

+ +

En primer lugar, hemos ido a Google Fonts y hemos encontrado un tipo de letra adecuado para una tabla sobre bandas punk. Puedes buscar uno diferente si lo deseas; solo tienes que reemplazar el elemento {{htmlelement ("link")}} que te hemos proporcionado y la declaración {{cssxref ("font-family")}} personalizada por las que te proporcione Google Fonts.

+ +

Primero, añade el elemento {{htmlelement ("link")}} siguiente a tu encabezado HTML, justo encima del elemento <link>:

+ +
<link href='https://fonts.googleapis.com/css?family=Rock+Salt' rel='stylesheet' type='text/css'>
+ +

Ahora añade el CSS siguiente a tu archivo style.css, debajo de la línea añadida anterior:

+ +
/* typography */
+
+html {
+  font-family: 'helvetica neue', helvetica, arial, sans-serif;
+}
+
+thead th, tfoot th {
+  font-family: 'Rock Salt', cursive;
+}
+
+th {
+  letter-spacing: 2px;
+}
+
+td {
+  letter-spacing: 1px;
+}
+
+tbody td {
+  text-align: center;
+}
+
+tfoot th {
+  text-align: right;
+}
+ +

En realidad aquí no hay nada que sea específico para las tablas. En general, modificamos el estilo de la letra para facilitar la lectura:

+ + + +

El resultado se ve un poco más limpio:

+ +

+ +

Gráficos y colores

+ +

Ahora, ¡a por los gráficos y los colores! Puesto que la tabla rezuma contenido y actitud punk, vamos a darle un brillante estilo imponente que le pegue. No te preocupes, no tienes que hacer tus tablas tan extremadas: puedes optar por algo más sutil y de buen gusto.

+ +

Empieza añadiendo el CSS siguiente a tu archivo style.css, de nuevo al final:

+ +
thead, tfoot {
+  background: url(leopardskin.jpg);
+  color: white;
+  text-shadow: 1px 1px 1px black;
+}
+
+thead th, tfoot th, tfoot td {
+  background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.5));
+  border: 3px solid purple;
+}
+
+ +

Una vez más, aquí no hay nada específico para las tablas, pero vale la pena señalar algunas cosas.

+ +

Hemos añadido una imagen de fondo ({{cssxref("background-image")}}) a los elementos {{htmlelement("thead")}} y {{htmlelement("tfoot")}}, y hemos cambiado el ({{cssxref("color")}}) de todo el texto del encabezado y el pie de página por el blanco (y le hemos dado una sombra, {{cssxref("text-shadow")}}) para que sea legible. Siempre debes asegurarte de que tu texto contraste bien con el fondo, para que sea legible.

+ +

También hemos añadido un degradado lineal a los elementos {{htmlelement("th")}} y {{htmlelement("td")}} del encabezado y el pie de página para obtener un poco de textura, y también hemos dado a esos elementos un borde púrpura brillante. Es útil tener múltiples elementos anidados disponibles para que puedas superponer estilos. Sí, podríamos haber colocado tanto la imagen de fondo como el gradiente lineal en los elementos {{htmlelement ("thead")}} y {{htmlelement ("tfoot")}} utilizando múltiples imágenes de fondo, pero decidimos hacerlo por separado por los navegadores más antiguos que no admiten múltiples imágenes de fondo o gradientes lineales.

+ +

Rayas de cebra

+ +

Queremos dedicar una sección independiente a mostrarte cómo implementar rayas de cebra, alternando filas de color que facilitan el análisis y la legibilidad de las diversas filas de datos de la tabla. Añade el CSS siguiente al final de tu archivo style.css:

+ +
tbody tr:nth-child(odd) {
+  background-color: #ff33cc;
+}
+
+tbody tr:nth-child(even) {
+  background-color: #e495e4;
+}
+
+tbody tr {
+  background-image: url(noise.png);
+}
+
+table {
+  background-color: #ff33cc;
+}
+ + + +

Esta explosión de colores da como resultado el aspecto siguiente:

+ +

+ +

Esto puede quedar un poco exagerado y no ser de tu agrado, pero el punto que tratamos de explicar es que las tablas no tienen por qué ser aburridas ni académicas.

+ +

Aplicar estilo al título

+ +

Hay una última cosa que hacer con nuestra tabla: aplicar estilo al título. Para ello, añade al final de tu archivo style.css lo siguiente:

+ +
caption {
+  font-family: 'Rock Salt', cursive;
+  padding: 20px;
+  font-style: italic;
+  caption-side: bottom;
+  color: #666;
+  text-align: right;
+  letter-spacing: 1px;
+}
+ +

Aquí no hay nada notable, excepto la propiedad {{cssxref ("caption-side")}}, a la que se le ha dado un valor bottom. Esto coloca el título en la parte inferior de la tabla, lo que junto con el resto de declaraciones nos proporciona este aspecto final (puedes verlo vivo en punk-bands-complete.html):

+ +

+ +

Aprendizaje activo: Aplica estilo a tu tabla

+ +

En este punto, nos gustaría que tomes nuestro ejemplo de tabla HTML (¡o que uses uno propio!) y que le apliques estilo para obtener algo considerablemente mejor diseñado y menos llamativo que nuestra tabla.

+ +

Consejos rápidos para el diseño de tablas

+ +

Antes de seguir adelante, creemos que tendríamos que proporcionar una lista rápida de los puntos más útiles que acabamos de ilustrar:

+ + + +

Resumen

+ +

Después de aplicar estilo a las tablas, necesitamos algo más en que ocupar nuestro tiempo. El artículo siguiente expone la depuración de documentos CSS, es decir, cómo resolver problemas como diseños de página que no presentan el aspecto que deberían, o propiedades que no se aplican cuando crees que deberían aplicarse. Esto incluye información sobre el uso de las herramientas DevTools del navegador para hallar soluciones a tus problemas.

+ +

{{PreviousMenuNext("Learn/CSS/Styling_boxes/Borders", "Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes")}}

diff --git a/files/es/learn/css/building_blocks/valores_y_unidades_css/index.html b/files/es/learn/css/building_blocks/valores_y_unidades_css/index.html new file mode 100644 index 0000000000..4470746bc8 --- /dev/null +++ b/files/es/learn/css/building_blocks/valores_y_unidades_css/index.html @@ -0,0 +1,392 @@ +--- +title: Valores y unidades CSS +slug: Learn/CSS/Building_blocks/Valores_y_unidades_CSS +translation_of: Learn/CSS/Building_blocks/Values_and_units +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks/Sizing_items_in_CSS", "Learn/CSS/Building_blocks")}}
+ +

Todas las propiedades que se utilizan en CSS tienen un valor o un conjunto de valores que esa propiedad admite, y echar un vistazo a cualquier página de propiedades en MDN te ayudará a comprender qué valores admite una propiedad en particular. En este artículo veremos algunos de los valores y unidades más comunes en uso.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajar con archivos, HTML básico (véase Introducción a HTML) y nociones de cómo funciona el CSS (véase Primeros pasos con el CSS).
Objetivo:Conocer los diferentes tipos de valores y unidades que admiten las propiedades CSS.
+ +

¿Qué es un valor CSS?

+ +

En las especificaciones CSS y en las páginas de propiedades de este proyecto MDN, podrás detectar los valores porque estarán escritos entre corchetes angulares, como <color> o <length>. Cuando veas que el valor <color> es válido para una propiedad en particular, significa que para esa propiedad puedes usar como valor cualquier color válido de entre los que se enumeran en la página de referencia de la propiedad <color>.

+ +
+

Nota: También verás valores CSS denominados tipos de datos. Los términos son básicamente intercambiables: cuando veas algo en CSS denominado ‘tipo de datos’, en realidad es solo una forma elegante de decir ‘valor’.

+
+ +
+

Nota: Sí, hay una tendencia de denotar los valores CSS entre corchetes angulares, para diferenciarlos de las propiedades CSS (por ejemplo, la propiedad {{cssxref ("color")}} con respecto al tipo de dato <color>). Aunque podría generarte confusión entre los tipos de datos CSS y los elementos HTML, porque ambos usan corchetes angulares, es poco probable porque se usan en contextos muy diferentes.

+
+ +

En el ejemplo siguiente hemos establecido el color de nuestro encabezado con una palabra clave y el fondo con la función rgb():

+ +
h1 {
+  color: black;
+  background-color: rgb(197,93,161);
+} 
+
+ +

Un valor en CSS es una forma de definir una colección de subvalores admitidos. Esto significa que si ves <color> como válido, no necesitas preguntarte cuáles de los diferentes tipos de valor de color puedes usar: palabras clave, valores hexadecimales, funciones rgb(), etc. Puedes usar cualquier valor <color> disponible siempre que tu navegador lo admita. La página de MDN te dará información sobre lo que admite cada navegador para cada valor. Por ejemplo, puedes ver que en la sección de compatibilidad de navegadores de la página para <color> se enumeran diferentes tipos de valores de color y los navegadores que los admiten.

+ +

Echemos un vistazo a algunos de los tipos de valores y unidades con los que puedes encontrar con frecuencia, con ejemplos para que puedas probar diferentes valores posibles.

+ +

Números, longitudes y porcentajes

+ +

Al utilizar CSS te puedes encontrar con varios tipos de datos numéricos. Todos los siguientes están clasificados como tipos de datos numéricos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Tipo de datosDescripción
<integer>Un <integer> es un número entero, como 1024 o -55.
<number>Un <number> representa un número decimal; puede tener o no un punto de separación decimal con un componente fraccionario, por ejemplo: 0,255, 128 o -1,2.
<dimension>Una <dimension> es un <number> con una unidad asociada, por ejemplo: 45deg (grados), 5s (segundos) o 10px (píxeles). <dimension> es una categoría general que incluye los tipos <length>, <angle>, <time> y <resolution>.
<percentage>Un <percentage> representa una fracción de algún otro valor, por ejemplo, 50%. Los valores de porcentaje siempre son relativos a otra cantidad, por ejemplo, la longitud de un elemento es relativa a la longitud de su elemento padre.
+ +

Longitudes

+ +

El tipo numérico con el que te vas a encontrar con mayor frecuencia es <length>, por ejemplo, 10px (píxeles) o 30em. En CSS se utilizan dos longitudes diferentes: relativa y absoluta. Es importante conocer la diferencia para entender qué dimensiones van a tener las cosas.

+ +

Unidades de longitud absoluta

+ +

Todas las unidades siguientes son unidades de longitud absoluta: no son relativas a nada más y en general se considera que siempre tienen el mismo tamaño.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UnidadNombreEquivale a
cmCentímetros1cm = 96px/2,54
mmMilímetros1mm = 1/10 de 1cm
QCuartos de milímetros1Q = 1/40 de 1cm
inPulgadas1in = 2,54cm = 96px
pcPicas1pc = 1/16 de 1in
ptPuntos1pt = 1/72 de 1in
pxPíxeles1px = 1/96 de 1in
+ +

La mayoría de estos valores son más útiles cuando se usan en una salida en formato impreso que en la salida de pantalla. Por ejemplo, normalmente no usamos cm (centímetros) en pantalla. El único valor que usarás de forma frecuente es px (píxeles).

+ +

Unidades de longitud relativa

+ +

Las unidades de longitud relativa son relativas a algo más, por ejemplo, al tamaño de letra del elemento principal o al tamaño de la ventana gráfica. La ventaja de usar unidades relativas es que con una planificación cuidadosa puedes lograr que el tamaño del texto u otros elementos escalen en relación con todo lo demás en la página. En la tabla siguiente se enumeran algunas de las unidades más útiles para el desarrollo web.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UnidadRelativa a
emTamaño de letra del elemento padre, en el caso de propiedades tipográficas como {{cssxref("font-size")}}, y tamaño de la fuente del propio elemento en el caso de otras propiedades, como {{cssxref("width")}}.
exAltura x de la fuente del elemento.
chLa medida de avance (ancho) del glifo "0" de la letra del elemento.
remTamaño de la letra del elemento raíz.
lhAltura de la línea del elemento.
vw1% del ancho de la ventana gráfica.
vh1% de la altura de la ventana gráfica.
vmin1% de la dimensión más pequeña de la ventana gráfica.
vmax1% de la dimensión más grande de la ventana gráfica.
+ +

Un ejemplo de análisis

+ +

En el ejemplo siguiente puedes ver cómo se comportan algunas unidades de longitud relativa y absoluta. La primera caja tiene un ancho ({{cssxref ("width")}}) establecido en píxeles. Como unidad absoluta, este ancho será siempre el mismo aunque lo demás cambie.

+ +

La segunda caja tiene un ancho establecido en unidades vw (ancho de ventana). Este valor es relativo al ancho de la ventana gráfica, por lo que 10vw es el 10 por ciento del ancho de la ventana gráfica. Si cambiases el ancho de la ventana de tu navegador, el tamaño de la caja cambiaría. Sin embargo, esto no te va a funcionar porque este ejemplo se ha incrustado en la página usando <iframe>. Para verlo en acción debes probar el ejemplo después de abrirlo en una pestaña independiente de tu navegador.

+ +

La tercera caja utiliza unidades em. Son unidades relativas al tamaño de la letra. Hemos establecido un tamaño de fuente de 1em en el contenido {{htmlelement ("div")}}, que tiene una clase .wrapper. Si cambias este valor a 1.5em, verás que el tamaño de letra de todos los elementos aumenta, pero solo se amplía el ancho en el último elemento, porque el ancho es relativo a ese tamaño de letra.

+ +

Después de seguir las instrucciones anteriores, juega un poco más con los valores para ver qué obtienes.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/length.html", '100%', 820)}}

+ +

ems y rems

+ +

em y rem son las dos longitudes relativas que es probable que encuentres con mayor frecuencia al cambiar el tamaño de cualquier cosa, de cajas a texto. Vale la pena entender cómo funcionan y las diferencias entre ellos, especialmente cuando comienzas a abordar temas más complejos como aplicar estilos a texto o compaginar con CSS. El ejemplo siguiente te proporciona una muestra.

+ +

El HTML es un conjunto de listas anidadas: hay tres listas en total y ambos ejemplos tienen el mismo HTML. La única diferencia es que el primero tiene una clase ems y el segundo una clase rems.

+ +

Para empezar, configuramos un tamaño de letra de 16px en el elemento <html>.

+ +

En definitiva, la unidad em significa «el tamaño de letra de mi elemento padre». Los elementos {{htmlelement ("li")}} dentro de un elemento {{htmlelement ("ul")}} con una clase de ems toman el tamaño con respecto a su elemento padre. Por lo tanto, en cada nivel de anidamiento sucesivo, el tamaño de letra aumenta progresivamente, porque en cada uno el tamaño de letra está establecido en 1.3em (1,3 veces el tamaño de letra de su elemento padre).

+ +

En definitiva, la unidad rem significa «el tamaño de letra del elemento raíz». (‘rem’ viene de «root em»). Los elementos {{htmlelement ("li")}} dentro de un elemento {{htmlelement ("ul")}} con una clase de rems toman su tamaño del elemento raíz (<html>). Esto significa que el tamaño de letra no aumenta en cada nivel sucesivo de anidamiento.

+ +

Sin embargo, si cambias el atributo font-size de <html> en el CSS, verás que todo lo demás cambia en relación con él, tanto la letra cuyo tamaño está especificado en unidades rem como la que lo está en unidades em.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/em-rem.html", '100%', 1000)}} 

+ +

Porcentajes

+ +

En muchos casos, un porcentaje es tratado de la misma manera que una longitud. Lo que sucede con los porcentajes es que siempre se establecen en relación con otro valor. Por ejemplo, si estableces el atributo font-size de un elemento como un porcentaje, será un porcentaje del font-size del elemento padre. Si usas un porcentaje para un valor width, será un porcentaje del atributo width del elemento padre.

+ +

En el ejemplo siguiente, las dos cajas con el tamaño especificado en unidades de porcentaje y las dos cajas con el tamaño especificado en unidades de píxel tienen los mismos nombres de clase. En ambos conjuntos de cajas, los anchos de las cajas son de 200 píxeles y de 40%, respectivamente.

+ +

La diferencia es que el segundo conjunto de dos cajas está dentro de un contenedor que tiene 400 píxeles de ancho. La segunda caja de 200 px de ancho tiene el mismo ancho que la primera, pero la segunda caja de 40% ahora es el 40% de 400 px, ¡mucho más estrecha que la primera!

+ +

Cambia el ancho del contenedor o el valor de porcentaje para ver cómo funciona.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/percentage.html", '100%', 850)}} 

+ +

El ejemplo siguiente tiene tamaños de letra establecidos en porcentajes. Cada elemento <li> tiene un atributo font-size del 80%, por lo tanto, los elementos de la lista anidada se vuelven progresivamente más pequeños a medida que heredan su tamaño del elemento padre.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/percentage-fonts.html", '100%', 650)}} 

+ +

Observa que aunque muchos valores admiten unidades de longitud o porcentaje, algunos solo admiten unidades de longitud. Puedes ver qué valores admite cada propiedad en las páginas de referencia correspondientes del proyecto MDN. Si el valor admitido incluye <length-percentage>, puedes usar una unidad de longitud o un porcentaje. Si el valor admitido solo incluye <length>, no es posible utilizar un porcentaje.

+ +

Números

+ +

Algunos valores aceptan números sin ninguna unidad asociada. Un ejemplo de una propiedad que acepta un número sin unidades es la propiedad opacity, que controla la opacidad de un elemento (cuán transparente es). Esta propiedad admite un número entre 0 (totalmente transparente) y 1 (totalmente opaco).

+ +

En el ejemplo siguiente, asigna al valor de opacity diversos valores decimales entre 0 y 1 para ver cómo la caja y su contenido cambian su opacidad.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/opacity.html", '100%', 500)}} 

+ +
+

Nota: Cuando en CSS utilizas un número como valor, no debe estar entre comillas.

+
+ +

Color

+ +

En CSS hay muchas formas de especificar el color, algunas de las cuales se implementaron más recientemente que otras. En todas partes en CSS se pueden usar los mismos valores de color, tanto para especificar el color del texto como el color de fondo, o de cualquier otra cosa.

+ +

El sistema de colores estándar disponible en los ordenadores modernos es de 24 bits, lo que permite visualizar aproximadamente 16,7 millones de colores distintos a partir de una combinación de diferentes canales de rojo, verde y azul con 256 valores diferentes por canal (256 x 256 x 256 = 16.777.216). Echemos un vistazo a algunas de las formas en que podemos especificar colores en CSS.

+ +
+

Nota: En este artículo vamos a ver los métodos comunes para especificar colores que admiten los navegadores; hay otros métodos no tan comunes que no admiten todos los navegadores.

+
+ +

Palabras clave para los colores

+ +

Muy a menudo, en los ejemplos de este artículo o en cualquier otra página de MDN, verás que se utilizan las palabras clave para los colores, ya que son una forma simple y comprensible de especificar colores. Hay una multitud de estas palabras clave, ¡algunas de las cuales tienen nombres de lo más curiosos! Puedes ver una lista completa en la página para el valor <color>.

+ +

Juega con diferentes valores de color en los ejemplos en vivo que encontrarás a continuación, para adquirir una idea más clara de cómo funcionan.

+ +

Los valores hexadecimales RGB

+ +

El siguiente tipo de valores de color que es probable que encuentres son los códigos hexadecimales. Cada valor hexadecimal consiste en un símbolo de hashtag/almohadilla (#) seguido de seis cifras hexadecimales, cada una de las cuales puede tomar uno de los 16 valores entre el 0 y la f (que representa el 15), por ejemplo: 0123456789abcdef. Cada par de cifras representa uno de los canales (rojo, verde y azul) y nos permite especificar cualesquiera de los 256 valores disponibles para cada uno (16 x 16 = 256).

+ +

Estos valores son un poco más complejos y menos fáciles de entender, pero son mucho más versátiles que las palabras clave: puedes usar valores hexadecimales para representar cualquier color que desees usar en tu combinación de colores.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/color-hex.html", '100%', 700)}} 

+ +

Una vez más, cambia los valores para ver cómo varían los colores.

+ +

Valores RGB y RGBA

+ +

El tercer esquema del que hablaremos aquí es RGB. Un valor RGB es una función rgb() que recibe tres parámetros que representan los valores de los canales rojo, verde y azul del color, de modo muy similar a los valores hexadecimales. La diferencia con RGB es que cada canal está representado no por dos dígitos hexadecimales, sino por un número decimal entre el 0 y el 255, lo que de algún modo resulta algo más fácil de entender.

+ +

Vamos a reescribir nuestro último ejemplo para utilizar colores RGB:

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/color-rgb.html", '100%', 700)}} 

+ +

También puedes usar colores RGBA: estos funcionan exactamente de la misma manera que los colores RGB, por lo que puedes usar cualquier valor RGB; sin embargo, hay un cuarto valor que representa el canal alfa del color, que controla la opacidad. Si estableces este valor en 0, el color será completamente transparente, mientras que en 1 será completamente opaco. Los valores intermedios le confieren diferentes niveles de transparencia.

+ +
+

Nota: Establecer un canal alfa en un color representa una diferencia clave para usar la propiedad {{cssxref ("opacity")}} que vimos anteriormente. Cuando usas la opacidad, el elemento y todo lo que contiene es opaco, mientras que cuando usas colores RGBA, solo son opacos los que especificas.

+
+ +

En el ejemplo siguiente hemos añadido una imagen de fondo al bloque que contiene nuestras cajas de color. También hemos configurado las cajas para que tengan diferentes valores de opacidad: observa que el fondo se muestra más cuanto menor es el valor del canal alfa.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/color-rgba.html", '100%', 770)}}

+ +

En este ejemplo, cambia los valores del canal alfa y observa cómo afecta a la salida de color.

+ +
+

Nota: En algún momento, los navegadores modernos se actualizaron para que rgba() y rgb(), y hsl() y hsla() (ver más abajo) se convirtieran en alias puros el uno del otro y comenzaran a comportarse exactamente igual. Así, por ejemplo, tanto rgba() como rgb() admiten colores con y sin valores de canal alfa. Cambia el rgba() del ejemplo anterior por rgb() y observa si los colores aún funcionan. El estilo que uses depende de ti, pero separar las definiciones de los colores transparentes y las de los no transparentes con el uso de funciones diferentes mejora la ejecución de los navegadores y puede actuar como un indicador visual de dónde se definen colores transparentes en tu código.

+
+ +

Los valores HSL y HSLA

+ +

Un poco menos compatible que RGB es el modelo de color HSL (no compatible con las antiguas versiones de Internet Explorer), que se implementó después de mucha insistencia por parte de los diseñadores. En lugar de los valores rojo, verde y azul, la función hsl() admite valores de matiz, saturación y luminosidad, que se utilizan para distinguir entre los 16,7 millones de colores, pero de una manera diferente:

+ + + +

Podemos adaptar el ejemplo con colores RGB para usar colores HSL, así:

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/color-hsl.html", '100%', 700)}} 

+ +

Al igual que RGB tiene un equivalente RGBA, HSL tiene un equivalente HSLA, que le proporciona la misma capacidad para especificar el canal alfa. Demostramos esto a continuación cambiando nuestro ejemplo RGBA para usar colores HSLA.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/color-hsla.html", '100%', 770)}} 

+ +

Puedes usar cualquiera de estos valores de color en tus proyectos. Es probable que para la mayoría de los proyectos te decidas por una paleta de colores y luego uses esos colores (y tu método elegido para especificar el color) en todo el proyecto. También puedes mezclar y combinar diversos modelos de color, sin embargo, por coherencia, en general es mejor si todo el proyecto usa el mismo.

+ +

Imágenes

+ +

El tipo de datos <image> se usa cuando una imagen es un valor válido. Puede ser un archivo de imagen real al que apunta una función url(), o un degradado.

+ +

En el ejemplo siguiente mostramos una imagen y un gradiente en uso como un valor para la propiedad CSS background-image.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/image.html", '100%', 740)}} 

+ +
+

Nota: hay otros valores posibles para <image>, pero son más nuevos y aún hay pocos navegadores que los admiten. Consulta la página de MDN para el tipo de dato <image> si deseas saber más sobre ellos.

+
+ +

Posición

+ +

El tipo de dato <position> representa un conjunto de coordenadas 2D que se utiliza para colocar un elemento, por ejemplo una imagen de fondo (con el atributo background-position). Puede tomar palabras clave como top, left, bottom, right y center para alinear los elementos con los límites específicos de una caja de dos dimensiones, y también longitudes, que representan desplazamientos desde los bordes superior e izquierdo de la caja.

+ +

Un valor de posición típico consta de dos valores: el primero establece la posición horizontal, y el segundo la vertical. Si solo especificas valores para un eje, el otro usará center por defecto.

+ +

En el ejemplo siguiente hemos colocado una imagen de fondo a 40px de la parte superior, y a la derecha del contenedor con una palabra clave.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/position.html", '100%', 720)}} 

+ +

Juega un poco con estos valores y observa cómo cambia la posición de la imagen.

+ +

Cadenas e identificadores

+ +

En los ejemplos anteriores hemos visto casos en que se usan palabras clave como valores (por ejemplo, palabras clave para <color>, como red, black, rebeccapurple y goldenrod). Estas palabras clave normalmente se describen como identificadores, un valor especial que el CSS entiende. Como tales, no se escriben entre comillas (es decir, no se tratan como cadenas).

+ +

Hay casos en el CSS en que debes usar cadenas, por ejemplo, al especificar el contenido que generas. En este caso, el valor se escribe entre comillas para mostrar que se trata de una cadena de caracteres. En el ejemplo siguiente hemos usado palabras clave para el color, sin entrecomillar, y también una cadena caracteres, de contenido generado, entrecomillada.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/strings-idents.html", '100%', 550)}} 

+ +

Funciones

+ +

El último tipo de valor que vamos a analizar es el grupo de valores conocidos como funciones. En programación, una función es un bloque de código reutilizable que es posible ejecutar varias veces para completar una tarea repetitiva con el mínimo esfuerzo tanto por parte del desarrollador como del ordenador. Las funciones suelen asociarse a lenguajes como JavaScript, Python o C++, pero también hay funciones en CSS, como valores de código propietario. Ya hemos visto funciones en acción en la sección sobre los colores: rgb(), hsl(), etc. El valor que se utiliza para devolver una imagen de un archivo, en este caso url(), también es una función.

+ +

Un valor que se comporta más como algo que puedes encontrar en un lenguaje de programación tradicional es la función calc(). Esta función te proporciona la capacidad de hacer cálculos simples en tu CSS. Es particularmente útil si deseas calcular valores que no puedes definir al escribir el CSS para tu proyecto y necesitas que el navegador lo haga durante la ejecución.

+ +

Por ejemplo, a continuación usamos calc() para hacer que la caja tenga 20% + 100px de ancho. El 20% se calcula a partir del ancho del contenedor principal .wrapper y, por lo tanto, cambiará si ese ancho cambia. No podemos hacer este cálculo de antemano porque no sabemos cuál será el 20% del elemento padre, por lo que usamos calc() para decirle al navegador que lo haga por nosotros.

+ +

{{EmbedGHLiveSample("css-examples/learn/values-units/calc.html", '100%', 450)}}

+ +

Pon a prueba tus conocimientos

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más importante? Encontrarás más pruebas para comprobar que retienes esa información antes de seguir en Test your skills: Values and units.

+ +

Resumen

+ +

Esta ha sido una revisión rápida de los tipos de valores y unidades más comunes que te puedes encontrar. Puedes echar un vistazo a todos los diferentes tipos en la página de referencia de valores y unidades CSS; encontrarás muchos de estos mientras trabajas en estos artículos.

+ +

Lo que debes recordar es que cada propiedad tiene una lista definida de valores admisibles, y cada valor incluye una definición que explica cuáles son sus subvalores. A continuación puedes buscar los detalles aquí, en MDN.

+ +

Por ejemplo, comprender que <image> también te permite crear un degradado de color es útil, ¡pero quizás no sea un conocimiento obvio!

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks/Sizing_items_in_CSS", "Learn/CSS/Building_blocks")}}

+ +

En este módulo

+ +
    +
  1. Cascada y herencia
  2. +
  3. Selectores CSS + +
  4. +
  5. El modelo de caja
  6. +
  7. Fondos y bordes
  8. +
  9. El uso de diferentes direcciones de texto
  10. +
  11. El desbordamiento de los contenidos
  12. +
  13. Los valores y las unidades
  14. +
  15. Elementos de dimensionado en CSS
  16. +
  17. Imágenes, media y elementos de formulario
  18. +
  19. Aplicar estilo a las tablas
  20. +
  21. Depurar el CSS
  22. +
  23. Organizar el CSS
  24. +
diff --git "a/files/es/learn/css/css_layout/dise\303\261o_receptivo/index.html" "b/files/es/learn/css/css_layout/dise\303\261o_receptivo/index.html" new file mode 100644 index 0000000000..4ddb7a94db --- /dev/null +++ "b/files/es/learn/css/css_layout/dise\303\261o_receptivo/index.html" @@ -0,0 +1,324 @@ +--- +title: Diseño receptivo +slug: Learn/CSS/CSS_layout/Diseño_receptivo +translation_of: Learn/CSS/CSS_layout/Responsive_Design +--- +
{{learnsidebar}}{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}
+ +

En los primeros días del diseño web, las páginas se diseñaban para llenar un tamaño de pantalla en particular. Si el usuario tenía una pantalla más grande o más pequeña que la del diseñador, los resultados esperados iban desde barras de desplazamiento no deseadas hasta longitudes de línea excesivamente largas y un mal uso del espacio. A medida que estuvieron disponibles tamaños de pantalla más diversos, apareció el concepto de diseño web responsivo (RWD, responsive web design), un conjunto de prácticas que permite a las páginas web alterar su diseño y apariencia para adaptarse a diferentes anchos de pantalla, resoluciones, etc. Es una idea que cambió la forma en que diseñamos para una web multidispositivo, y en este artículo te ayudaremos a comprender las principales técnicas que necesitas saber para dominarlo.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Primeros pasos en CSS y Los elementos básicos del CSS).
Objetivo:Comprender los conceptos fundamentales y la historia del diseño responsivo.
+ +

Diseños de sitios web históricos

+ +

En un momento de la historia, solo tenías dos opciones al diseñar un sitio web:

+ + + +

Estos dos enfoques tendían a dar como resultado un sitio web que se veía mejor ¡en la pantalla de la persona que diseñaba el sitio! El sitio líquido dio como resultado un diseño encogido en las pantallas que eran más pequeñas (como se ve a continuación) o longitudes de línea interminables en las pantallas que eran más grandes.

+ +
Un diseño de página con dos columnas encogidas en una ventana gráfica del tamaño de un teléfono móvil. +
+
+ +
+

Nota: Observa este ejemplo y su código fuente de un diseño líquido sencillo. Amplía o reduce la ventana del navegador y observa cómo cambia su aspecto en diferentes tamaños.

+
+ +

El sitio de ancho fijo se arriesgaba a una barra de desplazamiento horizontal en pantallas que eran más pequeñas que el ancho del sitio (como se ve a continuación), y a un gran espacio en blanco en los bordes del diseño en las pantallas que eran más grandes.

+ +
Un diseño con una barra de desplazamiento horizontal en una ventana de teléfono móvil. +
+
+ +
+

Nota: Observa este ejemplo y su código fuente de un diseño sencillo con un ancho fijo. Nuevamente, cambia el tamaño de la ventana del navegador y observa el resultado.

+
+ +
+

Nota: Las capturas de pantalla anteriores se han tomado usando el modo de diseño responsivo de las herramientas DevTools de Firefox.

+
+ +

A medida que la web móvil comenzó a hacerse realidad con los primeros teléfonos con funciones, las empresas que deseaban adoptar los dispositivos móviles solían crear una versión especial de su sitio web para dispositivo móvil, con una URL diferente (a menudo algo así como m.example.com o example.mobi). Esto significaba que había que desarrollar y actualizar dos versiones independientes del sitio web.

+ +

Además, estos sitios web para dispositivos móviles a menudo ofrecían una experiencia muy reducida. A medida que los dispositivos móviles se volvían más potentes y capaces de mostrar sitios web completos, esto resultaba frustrante para los usuarios de dispositivos móviles, que se veían atrapados en la versión móvil del sitio web y no podían acceder a la información que sabían que había en la versión de escritorio, que incluía todas las funciones del sitio web.

+ +

Diseño flexible antes del diseño responsivo

+ +

Se desarrollaron varios enfoques para tratar de resolver los inconvenientes de los métodos líquidos o de ancho fijo para crear sitios web. En 2004, Cameron Adams escribió una publicación titulada Resolution dependent layout, que describe un método para crear un diseño que podría adaptarse a diferentes resoluciones de pantalla. Este enfoque requería JavaScript para detectar la resolución de la pantalla y cargar el CSS correcto.

+ +

Zoe Mickley Gillenwater fue determinante en su trabajo de descripción y formalización de los diversos modos en que se podían crear sitios web flexibles para intentar encontrar una situación intermedia entre llenar toda la pantalla o tener un tamaño completamente fijo.

+ +

Diseño responsivo

+ +

El término diseño responsivo fue acuñado por Ethan Marcotte en 2010, y describía el uso combinado de tres técnicas.

+ +
    +
  1. La primera era la idea de las redes fluidas, algo que ya exploraba Gillenwater, y que puede leerse en el artículo de Marcotte, Fluid Grids (publicado en 2009 en A list apart).
  2. +
  3. La segunda técnica era la idea de las imágenes fluidas. Usando una técnica muy simple de establecer la propiedad de max-width al 100%, las imágenes se reducían si su columna de contención se volvía más estrecha que el tamaño intrínseco de la imagen, pero nunca se expandía. Esto permite reducir una imagen para que se ajuste a una columna de tamaño flexible, en lugar de que desborde, pero no se expande ni se pixela si la columna se ensancha más que la imagen.
  4. +
  5. El tercer componente clave era la consulta a los media. Las consultas a los media habilitan el tipo de cambio de diseño que Cameron Adams había explorado previamente usando JavaScript, pero usando solo CSS. En lugar de tener un único diseño para todos los tamaños de pantalla, el diseño podría cambiarse. Las barras laterales pueden reposicionarse en una pantalla más pequeña, o puede mostrarse una navegación alternativa.
  6. +
+ +

Es importante comprender que el diseño web responsivo no es una tecnología independiente: es un término utilizado para describir un enfoque para el diseño web, o un conjunto de buenas prácticas utilizado para crear un diseño que puede responder según el dispositivo que se utiliza para ver un contenido. En la exploración original de Marcotte, esto significaba cuadrículas flexibles (mediante elementos flotantes) y consultas de media; sin embargo, en los casi 10 años desde que se escribió ese artículo, trabajar de manera responsiva se ha convertido en la norma. Los métodos de diseño CSS modernos son inherentemente responsivos, y la plataforma web dispone de herramientas integradas nuevas que facilitan el diseño de sitios web responsivos.

+ +

El resto de este artículo te indicará las diversas características de la plataforma web que puedas querer utilizar para crear un sitio responsivo.

+ +

La consulta a los media

+ +

El diseño responsivo solo pudo surgir gracias a la consulta a los media. La especificación de nivel 3 de consulta a los media se convirtió en una candidata a Recomendación en 2009, lo que significa que se consideró lista para su implementación en los navegadores. Las consultas a los media nos permiten ejecutar una serie de pruebas (por ejemplo, si la pantalla del usuario es mayor que un ancho o una resolución determinados) y aplicar CSS selectivamente para diseñar la página de manera que resulte adecuada a las necesidades del usuario.

+ +

Por ejemplo, la consulta a los media siguiente explora si la página web que se muestra lo hace como un medio de pantalla (por lo tanto, no es un documento impreso) y si la ventana tiene al menos 800 píxeles de ancho. El CSS para el selector .container solo se aplicará si ambas condiciones son ciertas.

+ +
@media screen and (min-width: 800px) {
+  .container {
+    margin: 1em 2em;
+  }
+} 
+
+ +

Puedes añadir múltiples consultas a los media dentro de una hoja de estilo, y ajustar todo tu diseño o solo partes de él para que se adapte mejor a los diferentes tamaños de pantalla. Los puntos en los que se introduce una consulta a los media y se cambia el diseño se conocen como puntos de interrupción.

+ +

Un enfoque común cuando se usan las consultas a los media es crear un diseño sencillo de una sola columna para dispositivos de pantalla estrecha (por ejemplo, teléfonos móviles), luego implementar un diseño en columnas para pantallas más grandes cuando se sabe que hay suficiente ancho de pantalla para manejarlo. Esto se describe a menudo como diseño primero móvil.

+ +

Obtén más información sobre las consultas a los media en la documentación de MDN.

+ +

Cuadrículas flexibles

+ +

Los sitios responsivos no solo cambian su diseño entre puntos de interrupción, sino que se construyen sobre cuadrículas flexibles. Una cuadrícula flexible significa que no tienes que centrarte en todos los tamaños de dispositivo posibles y construir para ellos un diseño en píxeles perfecto. Ese enfoque sería imposible dada la gran cantidad de dispositivos de tamaños diferentes que hay, y el hecho de que, al menos en la versión de escritorio, las personas no siempre tienen la ventana de su navegador maximizada.

+ +

Al usar una cuadrícula flexible, solo necesitas añadir un punto de interrupción y cambiar el diseño en el punto en que el contenido comienza a verse mal. Por ejemplo, si las longitudes de las líneas se vuelven interminablemente largas a medida que el tamaño de la pantalla aumenta, o una caja se encoje hasta un ancho de dos palabras en cada línea a medida que el tamaño de la pantalla se reduce.

+ +

En los primeros días del diseño responsivo, nuestra única opción para el diseño de páginas web era usar elementos flotantes. Los diseños de pantalla con elementos flotantes flexibles se lograban dando a cada elemento un ancho porcentual asegurándose de que para toda la página no alcanzara más del 100%. En su trabajo original sobre cuadrículas fluidas, Marcotte detalló una fórmula para tomar un diseño de página web diseñado usando píxeles y convertirlo en porcentajes.

+ +
target / context = result 
+
+ +

Por ejemplo, si el tamaño de nuestra columna de destino es de 60 píxeles y el contexto (o contenedor) en el que se encuentra es de 960 píxeles, dividimos 60 por 960 para obtener un valor que podemos usar en nuestro CSS, después de mover el separador de cifras decimales dos posiciones a la derecha.

+ +
.col {
+  width: 6.25%; /* 60 / 960 = 0.0625 */
+} 
+
+ +

Este enfoque se encuentra hoy en muchos lugares de la web, y aquí está documentado en la sección de compaginación de nuestro artículo sobre métodos de compaginación heredados. Es probable que encuentres sitios web que utilizan este enfoque en su trabajo, por lo que vale la pena entenderlo, aunque no vas a construir un sitio web moderno utilizando una cuadrícula flexible basada en elementos flotantes.

+ +

El ejemplo siguiente muestra un diseño responsivo sencillo que utiliza consultas a los medios y una cuadrícula flexible. En pantallas estrechas, el diseño de página muestra las cajas en columna una encima de la otra:

+ +
Una vista de un dispositivo móvil con un diseño de página con cajas en columna vertical una encima de la otra. +
+
+ +

En pantallas más anchas se pasa a dos columnas:

+ +
Una vista de un dispositivo de escritorio con un diseño a dos columnas. +
+
+ +
+

Nota: Puedes encontrar el ejemplo en vivo y el código fuente de este ejemplo en GitHub.

+
+ +

Tecnologías modernas de diseño de páginas web

+ +

Los métodos modernos de diseño de páginas web, como el diseño en columnas, Flexbox y Grid son responsivos por defecto. Todos estos métodos asumen que tratas de crear una cuadrícula flexible y te proporcionan los modos más fáciles de hacerlo.

+ +

Multicol

+ +

El más antiguo de estos métodos de diseño de páginas web es multicol. Cuando especificas un atributo column-count, esto indica en cuántas columnas deseas dividir tu contenido. El navegador entonces calcula el tamaño de estas columnas, que cambiará de acuerdo con el tamaño de la pantalla.

+ +
.container {
+  column-count: 3;
+} 
+
+ +

Si en lugar de ello estableces el atributo column-width, especificas un ancho mínimo. El navegador crea tantas columnas de ese ancho como quepan cómodamente en el contenedor, y reparte el espacio entre todas las columnas. Por lo tanto, el número de columnas cambia según la cantidad de espacio que hay.

+ +
.container {
+  column-width: 10em;
+} 
+
+ +

Flexbox

+ +

En el método Flexbox, los elementos flexibles se encogen y distribuyen el espacio entre los elementos según el espacio que hay en su contenedor, según su comportamiento inicial. Al cambiar los valores de flex-grow y flex-shrink, puedes indicar cómo deseas que se comporten los elementos cuando a su alrededor hay más o menos espacio.

+ +

En el ejemplo siguiente, los elementos flexibles ocupan cada uno la misma cantidad de espacio en el contenedor flexible, al utilizar la abreviatura flex: 1 como se describe en el artículo Flexbox: Dimensionamiento flexible de los elementos flex.

+ +
.container {
+  display: flex;
+}
+
+.item {
+  flex: 1;
+} 
+
+ +
+

Nota: Como ejemplo, hemos reconstruido el anterior diseño de página responsivo sencillo, esta vez usando Flexbox. Puedes ver que ya no necesitamos usar valores de porcentaje extraños para calcular el tamaño de las columnas: ejemplo, código fuente.

+
+ +

Cuadrículas CSS

+ +

En el diseño de cuadrículas con CSS, la unidad fr permite la distribución del espacio disponible en las trazas de la cuadrícula. El ejemplo siguiente crea un contenedor de cuadrícula con tres trazas dimensionadas a 1fr. Esto crea tres columnas, cada una de las cuales ocupa una parte del espacio que hay disponible en el contenedor. Puedes obtener más información sobre este enfoque para crear una cuadrícula en el módulo Aprender a diseñar cuadrículas en Cuadrículas flexibles con la unidad fr.

+ +
.container {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+} 
+
+ +
+

Nota: La versión del diseño de página en cuadrícula es aún más simple, ya que podemos definir las columnas en .wrapper: ejemplo, código fuente.

+
+ +

Imágenes responsivas

+ +

El enfoque más simple para las imágenes responsivas es el que se describe en los primeros artículos de Marcotte sobre diseño responsivo. Básicamente, tomar una imagen que tenga el tamaño más grande que puedas necesitar, y reducirla. Este continúa siendo un enfoque utilizado hoy en día, y en la mayoría de las hojas de estilo encontrarás en alguna parte el CSS siguiente:

+ +
img {
+  max-width: 100%:
+} 
+
+ +

Hay inconvenientes obvios en este enfoque. La imagen puede mostrarse mucho más pequeña que su tamaño intrínseco, lo que representa una pérdida de ancho de banda: un usuario de dispositivo móvil puede descargar una imagen que sea varias veces el tamaño de lo que ve en realidad en la ventana del navegador. Además, es posible que no desees la misma relación de aspecto de la imagen en dispositivos móviles y en ordenadores de escritorio. Por ejemplo, podría ser bueno tener una imagen cuadrada para dispositivos móviles, pero mostrar la misma escena que una imagen horizontal en el escritorio. O bien es posible que, reconociendo el tamaño más pequeño de una imagen en dispositivos móviles, desees mostrar una imagen diferente, que se entienda mejor en un tamaño de pantalla pequeño. Estas cosas no se pueden lograr simplemente reduciendo una imagen.

+ +

Las imágenes responsivas, que utilizan el elemento {{htmlelement ("picture")}} y los atributos {{htmlelement ("img")}} srcset y sizes resuelven ambos problemas. Puedes proporcionar varios tamaños junto con «sugerencias» (metadatos que describen el tamaño de pantalla y la resolución para que la imagen sea la más adecuada), y el navegador elije la imagen que resulta más adecuada para cada dispositivo, y se asegura de que el usuario descarga un tamaño de imagen apropiado para el dispositivo que utiliza.

+ +

También puedes usar imágenes de director artístico, que proporcionan un recorte o una imagen completamente diferente para diferentes tamaños de pantalla.

+ +

Puedes encontrar una guía detallada de imágenes responsivas en el artículo sobre Aprender HTML en MDN.

+ +

Tipografía responsiva

+ +

Un elemento de diseño responsivo que todavía no hemos tratado en trabajos anteriores es la idea de la tipografía responsiva. Este concepto describe esencialmente el hecho de cambiar el tamaño de letra según el espacio de pantalla que reflejan las consultas a media.

+ +

En este ejemplo, queremos establecer que nuestro encabezado de nivel 1 sea 4rem, lo que significa que será cuatro veces nuestro tamaño de letra base. ¡Es un título muy grande! Solo queremos este título de encabezado gigante en los tamaños de pantalla más grandes, por lo tanto, primero creamos un título de encabezado más pequeño y luego usamos las consultas a los media para sobrescribirlo con el tamaño más grande si sabemos que el usuario tiene un tamaño de pantalla de al menos 1200px.

+ +
html {
+  font-size: 1em;
+}
+
+h1 {
+  font-size: 2rem;
+}
+
+@media (min-width: 1200px) {
+  h1 {
+    font-size: 4rem;
+  }
+} 
+
+ +

Hemos editado nuestro ejemplo anterior de cuadrícula responsiva para incluir también el tipo de respuesta utilizando el método descrito. Puedes ver cómo el título de encabezado cambia de tamaño cuando el diseño para a la versión de dos columnas.

+ +

En la versión para dispositivo móvil, el encabezado es más pequeño:

+ +
Un diseño de elementos apilados en columna con un tamaño de título de encabezado pequeño. +
+
+ +

Sin embargo, en las versiones de escritorio vemos un tamaño de título de encabezado más grande:

+ +
Un diseño en dos columnas con un título grande. +
+
+ +
+

Nota: Observa este ejemplo en: ejemplo, código fuente.

+
+ +

Como muestra este enfoque sobre la tipografía, no es necesario restringir las consultas a medios a cambiar solo el diseño de página. Se pueden usar para ajustar cualquier elemento y hacerlo más útil o atractivo según los diversos tamaños de pantalla.

+ +

El uso de unidades de ventana gráfica para tipografía responsiva

+ +

Un enfoque interesante es utilizar las unidades de ventana gráfica vw para habilitar la tipografía responsiva. 1vw es igual al uno por ciento del ancho de la ventana gráfica, lo que significa que si configuras el tamaño del tipo de letra con vw, siempre estará en relación con el tamaño de la ventana gráfica.

+ +
h1 {
+  font-size: 6vw;
+}
+ +

El problema de hacer esto es que el usuario pierde la posibilidad de ampliar cualquier conjunto de texto configurado en unidades vw, porque ese texto siempre está en relación con el tamaño de la ventana gráfica. Por lo tanto, nunca hay que establecer texto utilizando solo unidades de ventana.

+ +

Hay una solución, que implica el uso de la función calc(). Si añades la unidad vw a un valor establecido con un tamaño fijo, como em o rem, el texto continúa siendo ampliable. Esencialmente, la unidad vw se añade sobre ese valor ampliado:

+ +
h1 {
+  font-size: calc(1.5rem + 3vw);
+}
+ +

Esto significa que necesitamos especificar el tamaño de letra para el título de encabezado una sola vez, en lugar de configurarlo para dispositivos móviles y redefinirlo en las consultas a medios. Luego, el tipo de letra aumenta gradualmente a medida que aumenta el tamaño de la ventana gráfica.

+ +
+

Observa un ejemplo en: ejemplo, código fuente.

+
+ +

La metaetiqueta viewport

+ +

Si observas el tipo de letra de una página HTML responsiva, en general vas a encontrar la siguiente etiqueta {{htmlelement ("meta")}} en la cabecera del documento.

+ +
<meta name="viewport" content="width=device-width,initial-scale=1">
+
+ +

Esta metaetiqueta informa a los navegadores de los dispositivos móviles que deben establecer el ancho de la ventana gráfica al ancho del dispositivo y escalar el documento al 100% de ese tamaño, de modo que el documento se mostrará al tamaño optimizado para esos dispositivos móviles.

+ +

¿Por qué esto es necesario? Porque los navegadores de los dispositivos móviles tienden a mentir sobre el ancho de su ventana gráfica.

+ +

Esta metaetiqueta existe porque cuando se lanzó el iPhone original y la gente comenzó a ver sitios web en una pequeña pantalla de teléfono móvil, la mayoría de los sitios web no estaban optimizados para dispositivos móviles. Por lo tanto, el navegador móvil establecía el ancho de la ventana gráfica en 960 píxeles, representaba la página con ese ancho y mostraba el resultado como una versión reducida del diseño del escritorio. Otros navegadores de dispositivos móviles (por ejemplo, en Google Android) hicieron lo mismo. Los usuarios podían acercarse y desplazarse por el sitio web para ver las partes que les interesaban, pero se veía mal. Todavía verás esto hoy en día si tienes la desgracia de encontrarte con un sitio web que no tiene un diseño de página responsivo.

+ +

El problema es que tu diseño responsivo con puntos de interrupción y consultas a media no va a funcionar según lo previsto en los navegadores de dispositivos móviles, si tienes un diseño de pantalla estrecho que se inicia con un ancho de ventana de 480px o menos, pero la ventana gráfica está configurada en 960px. E cambio, al configurar width=device-width anulas el ancho predeterminado width=960px de Apple con el ancho real del dispositivo, y tus consultas a media funcionarán según lo previsto.

+ +

Por lo tanto, siempre debes incluir la línea de HTML anterior en la cabecera de tus documentos.

+ +

Con la metaetiqueta viewport puedes usar otras configuraciones, aunque, en general vas a querer usar la línea anterior.

+ + + +

Deberías evitar el uso de minimum-scale y maximum-scale, y en particular establecer user-scalable en no. Hay que permitir a los usuarios hacer zoom tanto o tan poco como lo necesiten; evitarlo provoca problemas de accesibilidad.

+ +
+

Nota: Hay una @regla CSS establecida para reemplazar la metaetiqueta viewport: @viewport. Sin embargo, tiene poca compatibilidad con los navegadores. Se implementó en Internet Explorer y Edge, pero una vez que se lance el navegador Edge basado en Chromium, dejará de formar parte del navegador Edge.

+
+ +

Resumen

+ +

El diseño responsivo se refiere a un diseño página de un sitio web o una aplicación que responde al entorno en el que se visualiza. Abarca una serie de características y técnicas de CSS y HTML, y ahora es esencialmente el modo como construimos los sitios web de forma predeterminada. Piensa en los sitios web que visitas con tu dispositivo móvil; probablemente sea inusual encontrar un sitio web que tenga la versión de escritorio reducida o en que necesites desplazarse hacia los lados para encontrar las cosas. Esto se debe a que la web se ha movido a este enfoque de diseño responsivo.

+ +

Además, lograr diseños responsivos se ha vuelto mucho más fácil con la ayuda de los métodos de diseño que has aprendido en estos artículos. Si eres nuevo en el desarrollo web, hoy tienes muchas más herramientas a tu disposición que en los primeros días del diseño de página responsivo. Por lo tanto, vale la pena verificar la antigüedad de los materiales que consultas. Si bien los artículos históricos continúan siendo útiles, el uso moderno de CSS y HTML facilita mucho la creación de diseños elegantes y útiles, sin importar con qué dispositivo el visitante visita el sitio.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-column_Layout", "Learn/CSS/CSS_layout/Media_queries", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/css_layout/flexbox/index.html b/files/es/learn/css/css_layout/flexbox/index.html new file mode 100644 index 0000000000..5d2b8cdf36 --- /dev/null +++ b/files/es/learn/css/css_layout/flexbox/index.html @@ -0,0 +1,337 @@ +--- +title: Flexbox +slug: Learn/CSS/CSS_layout/Flexbox +translation_of: Learn/CSS/CSS_layout/Flexbox +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Normal_Flow", "Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout")}}
+ +

Flexbox es un método de diseño de página unidimensional para compaginar elementos en filas o columnas. Los elementos de contenido se ensanchan para rellenar el espacio adicional y se encogen para caber en espacios más pequeños. En este artículo expondremos todas sus características básicas.

+ + + + + + + + + + + + +
Prerrequisitos:Los conceptos básicos de HTML (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Introducción al CSS).
Objetivo:Aprender a usar el sistema de compaginación con elementos flexbox para crear compaginaciones web.
+ +

¿Por qué flexbox?

+ +

Durante mucho tiempo, las únicas herramientas fiables con compatibilidad cruzada entre navegadores disponibles para crear diseños CSS fueron cosas como la flotación y el posicionamiento. Están bien y funcionan, pero de alguna manera también limitan bastante y frustran.

+ +

Con tales herramientas resulta difícil, si no imposible, lograr obtener en cualquier forma conveniente y flexible un diseño de página sencillo con unos requisitos como los siguientes:

+ + + +

Como verás en las secciones siguientes, los elementos flexbox facilitan mucho algunas tareas de compaginación. ¡Vamos a profundizar en ello!

+ +

Presentación de un ejemplo sencillo

+ +

En este artículo, te guiaremos por una serie de ejercicios para ayudarte a comprender cómo funcionan los elementos flexbox. Para comenzar, debes hacer una copia local del primer archivo de inicio flexbox0.html de nuestro repositorio de GitHub. Cárgalo en un navegador moderno (como Firefox o Chrome) y echa un vistazo al código en tu editor de código. Puedes verlo en vivo aquí.

+ +

Verás que hay un elemento {{htmlelement ("header")}} con un encabezado de nivel superior en él, y un elemento {{htmlelement ("section")}} que contiene tres elementos {{htmlelement ("article")}}. Los usaremos para crear una compaginación bastante habitual de tres columnas.

+ +

+ +

Especificar qué elementos colocar como cajas flexibles

+ +

Para comenzar, vamos a seleccionar qué elementos se van a presentar como cajas flexibles. Para ello, establecemos un valor especial de {{cssxref ("display")}} en el elemento padre de los elementos que deseas editar. En este caso, queremos compaginar los elementos {{htmlelement ("article")}}, por lo que lo establecemos en {{htmlelement ("section")}} (que se convierte en un contenedor flexible):

+ +
section {
+  display: flex;
+}
+ +

Esto hace que el elemento <section> se convierta en contenedor flex, y sus hijos en elementos flexibles. El resultado de esto debería ser algo así:

+ +

+ +

Así, esta declaración única nos da todo lo que necesitamos. Increíble, ¿verdad? Tenemos nuestra compaginación en columnas múltiples con columnas de igual tamaño, y todas las columnas tienen la misma altura. Esto se debe a que los valores por defecto que se han asignado a los elementos flexibles (los elementos secundarios del contenedor flexible) están pensados para resolver problemas comunes como este. Veremos más sobre el tema más adelante.

+ +

Para que quede claro, reiteremos lo que está sucediendo aquí. El elemento al que le hemos dado un valor de {{cssxref("display")}} de flex actúa como un elemento a nivel de bloque en términos de cómo interactúa con el resto de la página, pero sus elementos secundarios se presentan como elementos flexibles. La siguiente sección explicará con más detalle qué significa esto. Ten en cuenta también que puede usar un valor de display de inline-flex si desea diseñar los elementos secundarios de un elemento como elementos flexibles, pero hacer que ese elemento se comporte como un elemento en línea.

+ +

+

El modelo flexible

+ + +

Cuando los elementos se presentan como cajas flexibles, se distribuyen con respecto a dos ejes:

+ +

flex_terms.png

+ + + +

Ten presente esta terminología al avanzar por las secciones posteriores. Si en algún momento te confundes con el uso de estos conceptos, siempre puedes volver atrás a consultarlos.

+ +

¿Columnas o filas?

+ +

Los elementos flexbox proporcionan una propiedad llamada {{cssxref ("flex-direction")}} que especifica en qué dirección corre el eje principal (en qué dirección están dispuestos los elementos hijo de un elemento flexbox); por defecto, está establecido en el valor row, por lo que se presenta en una fila en la dirección en que se escribe el idioma predeterminado de tu navegador (de izquierda a derecha, en el caso de un navegador en español).

+ +

Añade la declaración siguiente a tu regla {{htmlelement ("section")}}:

+ +
flex-direction: column;
+ +

Observa que esto vuelve a colocar los elementos en una disposición en columna, al igual que antes de añadir cualquier CSS. Antes de continuar, elimina esta declaración de tu ejemplo.

+ +
+

Nota: También puedes compaginar elementos flexibles en una dirección inversa utilizando los valores row-reverse y column-reverse. ¡Experimenta también con estos valores!

+
+ +

Delimitar

+ +

Un problema que surge cuando tienes una cantidad fija de ancho o alto en tu diseño es que los hijos de un elemento flexbox eventualmente desbordan el contenedor y rompen el diseño. Echa un vistazo a nuestro ejemplo flexbox-wrap0.html e intenta verlo en vivo (toma una copia local de este archivo si deseas seguir este ejemplo):

+ +

+ +

Aquí vemos que los elementos hijo se salen de su contenedor. Una forma de solucionar esto es añadir la declaración siguiente a tu regla {{htmlelement ("section")}}:

+ +
flex-wrap: wrap;
+ +

Añade también la declaración siguiente a tu regla {{htmlelement ("article")}}:

+ +
flex: 200px;
+ +

Pruébalo; observa que al haberlo incluido el aspecto de la compaginación resulta mucho más agradable:

+ +

Ahora hay varias filas y en cada fila caben tantos elementos hijo de un elemento flexbox como sean necesarios, y cualquier desbordamiento hace saltar el elemento hacia la línea siguiente. La declaración flex: 200px que hemos establecido en los artículos significa que cada uno tendrá al menos 200 px de ancho; discutiremos esta propiedad con más detalle más adelante. Observa también que los últimos elementos hijo de la última fila se agrandan hasta rellenar toda la fila.

+ +

Pero aquí podemos hacer mucho más. En primer lugar, cambia el valor de tu propiedad {{cssxref ("flex-direction")}} a row-reverse; ahora verás que todavía tienes tu compaginación en diversas filas, pero comienza desde la esquina opuesta de la ventana del navegador y fluye al revés.

+ +

Propiedades abreviadas de flex-flow

+ +

En este punto vale la pena señalar que hay una propiedad abreviada para {{cssxref ("flex-direction")}} y {{cssxref ("flex-wrap")}}: {{cssxref ("flex-flow")}}. Así, por ejemplo, puedes reemplazar:

+ +
flex-direction: row;
+flex-wrap: wrap;
+ +

con

+ +
flex-flow: row wrap;
+ +

Dimensionamiento flexible de elementos flexibles

+ +

Volvamos ahora a nuestro primer ejemplo y veamos cómo podemos controlar qué proporción de espacio ocupan los elementos flexibles. Inicia tu copia local de flexbox0.html o toma una copia de flexbox1.html como nuevo punto de partida (consúltalo en vivo).

+ +

Primero, añade la regla siguiente al final de tu CSS:

+ +
article {
+  flex: 1;
+}
+ +

Este es un valor de proporción sin unidades que especifica la cantidad de espacio disponible sobre el eje principal que ocupa cada elemento flexible. En este caso, damos a cada elemento {{htmlelement ("article")}} un valor de 1, lo que significa que todos ocuparán una cantidad igual del espacio libre restante después de que se hayan establecido elementos como el área de relleno y el margen. Es una proporción, lo que significa que dar a cada elemento flexible un valor de 400000 tendría exactamente el mismo efecto.

+ +

Ahora añade la regla siguiente debajo de la anterior:

+ +
article:nth-of-type(3) {
+  flex: 2;
+}
+ +

Al actualizar verás que el tercer {{htmlelement ("article")}} ocupa ahora el doble del ancho disponible que los otros dos; ahora hay cuatro unidades de proporción disponibles en total. Los primeros dos elementos flexibles tienen una cada uno, por lo que ocupan 1/4 del espacio disponible cada uno. El tercero tiene dos unidades, por lo que ocupa 2/4 del espacio disponible (o 1/2).

+ +

También puedes especificar un valor de tamaño mínimo dentro del valor flexible. Actualiza las reglas para tu artículo de la manera siguiente:

+ +
article {
+  flex: 1 200px;
+}
+
+article:nth-of-type(3) {
+  flex: 2 200px;
+}
+ +

Esto establece básicamente que «a cada elemento flexible se le da primero 200px del espacio disponible. Después de eso, el resto del espacio disponible se reparte de acuerdo con las unidades de proporción». Actualiza y observa de qué modo se reparte ahora el espacio.

+ +

+ +

El valor real del elemento flexbox se puede ver en su flexibilidad/adaptabilidad: si cambias el tamaño de la ventana del navegador o añades otro elemento {{htmlelement ("article")}}, el diseño continúa funcionando bien.

+ +

flex: forma completa y abreviada

+ +

{{cssxref ("flex")}} es una propiedad abreviada que puede especificar hasta tres valores diferentes:

+ + + +

Recomendamos no usar las propiedades flex sin abreviar a menos que realmente tengas que hacerlo (por ejemplo, para anular algo establecido previamente). Comportan mucho código añadido y suelen aportar confusión.

+ +

Alineación horizontal y vertical

+ +

También puedes usar las funciones de los elementos flexbox para alinear elementos flexibles sobre el eje principal o transversal. Exploremos este aspecto a partir de un ejemplo nuevo: flex-align0.html (consúltalo en vivo), que vamos a convertir en una barra de herramientas/botones ordenada y flexible. En este momento puedes ver una barra de menú horizontal, con algunos botones pegados en línea a la esquina superior izquierda.

+ +

+ +

Primero, toma una copia local de este ejemplo.

+ +

Ahora, añade a la parte inferior del CSS del ejemplo lo siguiente:

+ +
div {
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+}
+ +

Actualiza la página y observa que los botones ahora están convenientemente centrados, horizontal y verticalmente. Lo hemos hecho a partir de dos propiedades nuevas.

+ +

{{cssxref ("align-items")}} controla dónde se ubican los elementos flexibles en el eje transversal.

+ + + +

Puedes anular el comportamiento {{cssxref ("align-items")}} para elementos flexibles individuales aplicándoles la propiedad {{cssxref ("align-self")}}. Por ejemplo, añade a tu CSS lo siguiente:

+ +
button:first-child {
+  align-self: flex-end;
+}
+ +

Observa qué efecto tiene esto y retíralo de nuevo al terminar.

+ +

{{cssxref ("justify-content")}} controla dónde se ubican los elementos flexibles sobre el eje principal.

+ + + +

Te animamos a jugar con estos valores para ver cómo funcionan antes de continuar.

+ +

Ordenar los elementos flexibles

+ +

Los elementos flexbox también tienen una función para cambiar el orden de disposición de los elementos flexibles, sin que ello afecte a su orden en el código fuente. Esto es algo que resulta imposible de hacer con los métodos de compaginación tradicionales.

+ +

El código para esto es simple: añade el siguiente CSS al código de ejemplo de la barra de controles:

+ +
button:first-child {
+  order: 1;
+}
+ +

Actualiza, y observa que el botón «Smile» se ha movido al final del eje principal. Observemos cómo funciona esto con un poco más de detalle:

+ + + +

Puedes establecer valores de orden negativos para que los elementos aparezcan antes que los elementos establecidos con el valor 0. Por ejemplo, puedes hacer que el botón «Blush» aparezca al comienzo del eje principal utilizando la regla siguiente:

+ +
button:last-child {
+  order: -1;
+}
+ +

Cajas flexibles anidadas

+ +

Los elementos flexbox permiten crear algunos diseños de página bastante complejos. Es perfectamente aceptable configurar un elemento flexible para que también sea un contenedor flexible, de modo que los elementos secundarios también se dispongan como cajas flexibles. Echa un vistazo a complex-flexbox.html (consúltalo en vivo).

+ +

+ +

El HTML para ello es bastante simple. Hay un elemento {{htmlelement ("section")}} que contiene tres elementos {{htmlelement ("article")}}. El tercer elemento {{htmlelement ("article")}} contiene tres elementos {{htmlelement ("div")}}:

+ +
section - article
+          article
+          article - div - button
+                    div   button
+                    div   button
+                          button
+                          button
+ +

Veamos el código que hemos usado para esta compaginación.

+ +

En primer lugar, configuramos los elementos secundarios de {{htmlelement ("section")}} para que se presenten como cajas flexibles.

+ +
section {
+  display: flex;
+}
+ +

A continuación, establecemos algunos valores flexibles en los elementos {{htmlelement ("article")}}. Presta una atención especial a la segunda regla: configuramos el tercer elemento {{htmlelement ("article")}} para que sus hijos también se presenten como elementos flexibles, pero esta vez los disponemos en una columna.

+ +
article {
+  flex: 1 200px;
+}
+
+article:nth-of-type(3) {
+  flex: 3 200px;
+  display: flex;
+  flex-flow: column;
+}
+
+ +

A continuación, seleccionamos el primer elemento {{htmlelement ("div")}}. Primero usamos flex:1 100px; para darle una altura mínima efectiva de 100 px, luego configuramos sus elementos secundarios (los elementos {{htmlelement ("button")}}) para que también se presenten como elementos flexibles. Aquí los colocamos en una fila que los delimita y los alineamos en el centro del espacio disponible, como hicimos en el ejemplo del botón individual que vimos antes.

+ +
article:nth-of-type(3) div:first-child {
+  flex:1 100px;
+  display: flex;
+  flex-flow: row wrap;
+  align-items: center;
+  justify-content: space-around;
+}
+ +

Por último, establecemos un tamaño para el botón, pero lo más interesante es que le damos un valor flexible de 1 auto. Esto tiene un efecto muy interesante, que puedes observar si cambias el tamaño del ancho de la ventana de tu navegador. Los botones ocuparán tanto espacio como puedan y se asentarán tantos en la misma línea como quepan, pero cuando ya no quepan con comodidad en la misma línea, saltarán de línea y crearán líneas nuevas.

+ +
button {
+  flex: 1 auto;
+  margin: 5px;
+  font-size: 18px;
+  line-height: 1.5;
+}
+ +

Compatibilidad entre navegadores

+ +

La compatibilidad de los elementos flexbox está garantizada para la mayoría de los navegadores nuevos: Firefox, Chrome, Opera, Microsoft Edge e Internet Explorer 11, las versiones más recientes de Android/iOS, etc. Sin embargo, todavía hay navegadores antiguos en uso que no admiten las propiedades flexbox (o lo hacen, pero admiten una versión muy antigua y desactualizada).

+ +

Esto no importa demasiado mientras estás aprendiendo y experimentando; pero cuando consideras usar propiedades flexbox en un sitio web real, debes hacer pruebas y asegurarte de que tu experiencia de usuario sea lo suficientemente aceptable en tantos navegadores como sea posible.

+ +

Las propiedades flexbox son un poco más complicadas que otras características de CSS. Por ejemplo, si un navegador no soporta sombras en CSS, es probable que el sitio todavía sea utilizable. Sin embargo, si no es compatible con las funciones flexbox, probablemente el diseño completo se romperá, y el sitio web se inutilizará.

+ +

Expusimos estrategias para superar problemas de compatibilidad entre navegadores en nuestro módulo Pruebas de compatibilidad del navegador.

+ +

Pon a prueba tus habilidades

+ +

Hemos cubierto mucho terreno en este artículo. ¿Recuerdas la información más importante? Encontrarás más pruebas para comprobar si retienes esta información antes de seguir en Test your skills: Flexbox.

+ +

Resumen

+ +

Con esto concluye nuestro recorrido por los conceptos básicos de las propiedades flexbox. Esperamos que te hayas divertido y que juegues con ello mientras avanzas en tu aprendizaje. A continuación, veremos otro aspecto importante de los diseños CSS: las rejillas CSS.

+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Normal_Flow", "Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout")}}
+ +
+

En este módulo

+ + +
diff --git a/files/es/learn/css/css_layout/floats/index.html b/files/es/learn/css/css_layout/floats/index.html new file mode 100644 index 0000000000..47ae275f2e --- /dev/null +++ b/files/es/learn/css/css_layout/floats/index.html @@ -0,0 +1,505 @@ +--- +title: Floats +slug: Learn/CSS/CSS_layout/Floats +translation_of: Learn/CSS/CSS_layout/Floats +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout")}}
+ +

Originalmente pensada para flotar imágenes dentro de bloques de texto, la propiedad {{cssxref("float")}} se convirtió en una de las herramientas más usadas para crear diseños multicolumna en las páginas web. Con la llegada de Flexbox y Grid ha vuelto ahora a su propósito original, como se explica en este artículo.

+ + + + + + + + + + + + +
Requisitos previos:HTML básico (ver Introducción al HTML), y una idea de Cómo funciona CSS (ver Introducción a CSS.)
Objetivo:Aprender a crear elementos flotantes en páginas web, y a usar la propiedad clear y otros métodos para limpiar los elementos flotantes.
+ +

La historia de los elementos flotantes

+ +

La propiedad {{cssxref("float")}} fue introducida para permitir a los desarrolladores implementar diseños sencillos que incluyeran una imagen flotando dentro de una columna de texto, con el texto envolviendo la parte izquierda o derecha de la imagen. El tipo de cosa que encuentras habitualmente en el diseño de un periódico.

+ +

Pero los desarrolladores web pronto se dieron cuenta de que podían flotar cualquier cosa, no solo imágenes, por lo que su uso se extendió, por ejemplo creando efectos de diseño divertidos como estas letras capitulares.

+ +

Los elementos flotantes han sido usados comúnmente para crear diseños web completos con múltiples columnas situadas unas al lado de las otras (el comportamiento por defecto sería que las columnas se situaran unas debajo de las otras, en el mismo orden en el que aparecen en el código fuente). Ahora hay disponibles técnicas más modernas y mejores, que exploraremos más adelante en este módulo, por lo que el uso de {{cssxref("float")}} de este modo debería contemplarse como una técnica anticuada.

+ +

En este artículo nos centraremos en el uso apropiado de la propiedad {{cssxref("float")}}.

+ +

Un ejemplo de float simple

+ +

Exploremos cómo usar los float. Empezaremos con un ejemplo realmente simple que incluye un bloque de texto flotando alrededor de un elemento. Puedes acompañarnos creando un fichero index.html en tu ordenador, rellenándolo con una plantilla HTML simple, e insertando el código siguiente en los lugares adecuados. Al final de la sección podrás ver un ejemplo en vivo de cómo debería ser el código final.

+ +

Primero, empecemos con algo de HTML simple — añade lo siguiente al cuerpo de tu HTML, eliminando cualquier otra cosa que hubiera antes:

+ +
<h1>Ejemplo simple de caja flotante</h1>
+
+<div class="box">Caja flotante</div>
+
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. </p>
+
+<p>Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
+
+<p>Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
+ +

Ahora aplica el siguiente CSS a tu HTML (usando un elemento {{htmlelement("style")}} o un {{htmlelement("link")}} para separar el fichero .css  — tú eliges):

+ +
body {
+  width: 90%;
+  max-width: 900px;
+  margin: 0 auto;
+  font: .9em/1.2 Arial, Helvetica, sans-serif
+}
+
+.box {
+  width: 150px;
+  height: 100px;
+  border-radius: 5px;
+  background-color: rgb(207,232,220);
+  padding: 1em;
+}
+ +

Si guardas y recargas la página, verás algo parecido a lo que esperarías: la caja se encuentra por encima del texto, en un flujo normal. Para flotar el texto alrededor, añade las propiedades {{cssxref("float")}} y {{cssxref("margin-right")}} a la regla .box:

+ +
.box {
+  float: left;
+  margin-right: 15px;
+  width: 150px;
+  height: 100px;
+  border-radius: 5px;
+  background-color: rgb(207,232,220);
+  padding: 1em;
+}
+ +

Ahora, si guardas y recargas, podrás ver algo parecido a lo siguiente:

+ +
+ +
+ +

{{ EmbedLiveSample('Float_1', '100%', 500) }}

+ +

Analicemos ahora cómo funciona el float — el elemento con el float aplicado (el elemento {{htmlelement("div")}} en este caso) es sacado del flujo normal del documento y está pegado al lado izquierdo de su elemento contenedor padre ({{htmlelement("body")}}, en este caso). Cualquier contenido que esté por debajo del elemento flotado en el flujo normal, ahora lo envolverá, rellenando el espacio a la derecha hasta la parte superior del elemento flotante. Allí se detendrá.

+ +

Flotar el contenido a la derecha tiene exactamente el mismo efecto, pero a la inversa — el elemento flotado se pegará a la derecha, y el contenido lo envolverá por la izquierda. Prueba cambiando el valor de la propiedad float a right y reemplaza {{cssxref("margin-right")}} con {{cssxref("margin-left")}} en el último conjunto de reglas para ver el resultado.

+ +

Si bien podemos agregar un margen al flotante para alejar el texto, no podemos agregar un margen al texto para alejarlo del flotante. Esto se debe a que un elemento flotante se saca del flujo normal y las cajas de los siguientes elementos siguen detrás del flotador. Puedes comprobarlo haciendo algunos cambios en tu ejemplo.

+ +

Añade una clase special al primer párrafo de texto, el que sucede inmediatamente a la caja flotante, y luego añade en tu CSS las siguientes reglas. Esto le dará al párrafo siguiente un color de fondo.

+ +
.special {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  color: #fff;
+}
+
+ +

Para que el efecto sea más fácil de ver, cambia el margin-right de tu elemento flotante a margin, para obtener espacio alrededor del elemento flotante. Verás que el fondo del párrafo pasa justo por debajo de la caja flotante, como en el ejemplo inferior.

+ +
+ +
+ +

{{ EmbedLiveSample('Float_2', '100%', 500) }}

+ +

Los cuadros de línea de nuestro siguiente elemento se han acortado para que el texto discurra alrededor del flotador, pero debido a que el flotador se eliminó del flujo normal, el cuadro alrededor del párrafo aún permanece en ancho completo.

+ +

Limpiando floats

+ +

Hemos visto que el flotador se elimina del flujo normal y que otros elementos se mostrarán a su lado, por lo tanto, si queremos evitar que un elemento siguiente se mueva hacia arriba, debemos limpiar el float. Esto se logra con la propiedad {{cssxref ("clear")}}.

+ +

En el HTML del ejemplo anterior, añade una clase cleared al segundo párrafo debajo del elemento flotante. Luego añade lo siguiente a tu CSS:

+ +
.cleared {
+  clear: left;
+}
+
+ +
+ +
+ +

{{ EmbedLiveSample('Float_3', '100%', 600) }}

+ +

Deberías ver que el siguiente párrafo limpia el elemento flotante y ya no aparece junto a él. La propiedad clear acepta los siguientes valores:

+ + + +

Limpiar las cajas envueltas alrededor de un float

+ +

Ahora ya sabes cómo limpiar un elemento que sigue a un elemento flotante, pero observa lo que sucede si tienes un flotante alto y un párrafo corto, con una caja envolviendo a ambos elementos. Modifica tu documento para que el primer párrafo y el cuadro flotante estén envueltos por un {{htmlelement("div")}} con una clase wrapper.

+ +
<div class="wrapper">
+  <div class="box">Caja flotante</div>
+
+  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate.</p>
+</div>
+
+ +

En tu CSS, añade la siguiente regla para la clase .wrapper y después recarga la página:

+ +
.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  color: #fff;
+}
+ +

Además, elimina la clase .cleared anterior:

+ +
.cleared {
+    clear: left;
+}
+ +

Verás que, como en el ejemplo en el que hemos puesto un color de fondo al párrafo, el color de fondo pasa por detrás del elemento flotante.

+ +
+ +
+ +

{{ EmbedLiveSample('Float_4', '100%', 600) }}

+ +

Una vez más, esto se debe a que el flotador se ha sacado del flujo normal. Limpiar el siguiente elemento no ayuda con este problema de limpieza de caja, donde queremos que la parte inferior de la caja envuelva el elemento flotante y envuelva el contenido incluso si el contenido es más corto. Hay tres formas posibles de lidiar con esto, dos que funcionan en todos los navegadores, pero tienen algo de truco, y una tercera, nueva forma de lidiar con esta situación correctamente.

+ +

El hack clearfix

+ +

La forma en que esta situación se ha tratado tradicionalmente es utilizando algo conocido como "truco clearfix". Esto implica insertar algún contenido generado después del cuadro que contiene el contenido flotante y envolvente, y configurarlo para limpiar ambos.

+ +

Añade el siguiente CSS al ejemplo:

+ +
.wrapper::after {
+  content: "";
+  clear: both;
+  display: block;
+}
+ +

Ahora recarga la página y la caja debería limpiarse. Esto es básicamente lo missmo que si hubieras añadido un elemento HTML como un <div> debajo de los elementos y le hubieras añadido la propiedad clear: both.

+ +
+ +
+ +

{{ EmbedLiveSample('Float_5', '100%', 600) }}

+ +

Usando overflow

+ +

Un método alternativo es establecer la propiedad {{cssxref("overflow")}} del elemento envolvente con un valor distinto de visible.

+ +

Elimina el CSS clearfix que añadiste en la anterior sección y, en su lugar, añade overflow: auto a las reglas de la caja envolvente. De nuevo, la caja debería limpiarse.

+ +
.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  color: #fff;
+  overflow: auto;
+}
+ +
+ +
+ +

{{ EmbedLiveSample('Float_6', '100%', 600) }}

+ +

Este ejemplo funciona creando lo que se conoce como un block formatting context (BFC) o contexto de formato de bloque. Es como un pequeño diseño dentro de nuestra página dentro del cual todo está contenido, por lo tanto, nuestro elemento flotante está contenido dentro del BFC y el fondo se encuentra detrás de ambos elementos. Esto generalmente funcionará, sin embargo, en ciertos casos, es posible que encuentre barras de desplazamiento no deseadas o sombras recortadas debido a las consecuencias no deseadas del uso del desbordamiento..

+ +

display: flow-root

+ +

La manera moderna de resolver este problema es usar el valor flow-root de la propiedad display. Esto existe solo para crear un BFC sin usar hacks; no habrá consecuencias no deseadas cuando lo use. Elimina overflow: auto de la regla .wrapper y añade display: flow-root. Asumiendo que tu navegador sea compatible, la caja se limpiará.

+ +
.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  color: #fff;
+  display: flow-root;
+}
+ +
+ +
+ +

{{ EmbedLiveSample('Float_7', '100%', 600) }}

+ +

Resumen

+ +

Ahora ya sabes todo lo que tienes que saber sobre los flotadores en el desarrollo web moderno. Consulta el artículo sobre métodos de diseño anticuados para obtener información de cómo se solían usar, lo que puede serte útil si tienes que trabajar en proyectos antiguos.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Grids", "Learn/CSS/CSS_layout/Positioning", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/css_layout/flujo_normal/index.html b/files/es/learn/css/css_layout/flujo_normal/index.html new file mode 100644 index 0000000000..ffc873938f --- /dev/null +++ b/files/es/learn/css/css_layout/flujo_normal/index.html @@ -0,0 +1,95 @@ +--- +title: Flujo normal +slug: Learn/CSS/CSS_layout/Flujo_normal +translation_of: Learn/CSS/CSS_layout/Normal_Flow +--- +
{{LearnSidebar}}
+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

+ +

Este artículo explica el flujo normal, o la forma en que se presentan los elementos de la página web si no cambias su compaginación.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Introducción al CSS).
Objetivo:Conocer cómo los navegadores presentan de forma predeterminada las páginas web antes de comenzar a hacer cambios.
+ +

Como se detalla en el último artículo de introducción al diseño, los elementos en una página web se distribuyen según el flujo normal si no se aplica ningún CSS que cambie la forma en la que se comportan. Y, como comenzamos a descubrir, puedes cambiar el comportamiento de los elementos, ya sea ajustando su posición en este flujo normal o eliminándolos de este por completo. Comenzar con un documento coherente y bien estructurado que sea legible en el flujo normal es la mejor manera de comenzar cualquier página web. Asegura que tu contenido sea legible, incluso si el usuario usa un navegador muy limitado o un dispositivo como un lector de pantalla que lee el contenido de la página. Además, como el flujo normal está diseñado para que un documento sea legible, al comenzar de esta manera, trabajas en el documento en lugar de luchar contra él a medida que haces cambios en su diseño.

+ +

Antes de profundizar en los diferentes métodos de diseño, vale la pena revisar algunas de las cosas que ya debes haber estudiado en artículos anteriores con respecto al flujo normal de los documentos.

+ +

¿Cómo se presentan por defecto los elementos?

+ +

En primer lugar, se toma de las cajas de cada uno de los elementos el contenido, luego se añade cualquier área de relleno, borde y margen alrededor de ellas; es el modelo de cajas que hemos visto antes.

+ +

De manera predeterminada, el contenido de un elemento de nivel de bloque es el 100% del ancho de su elemento padre y su altura viene determinada por su contenido. Los elementos en línea tienen su altura y anchura determinados por su contenido. No puedes establecer el ancho o la altura de los elementos en línea, simplemente se ubican dentro del contenido de los elementos de nivel de bloque. Si deseas controlar el tamaño de un elemento en línea de esta manera, debes configurarlo para que se comporte como un elemento de nivel de bloque con display: block; (o incluso, display: inline-block;, que combina características de ambos).

+ +

Esto explica los elementos individuales, pero ¿qué hay del modo como los elementos interactúan entre sí? El flujo de diseño normal (mencionado en el artículo de introducción al diseño) es el sistema mediante el cual los elementos se colocan en la ventana gráfica del navegador. De manera predeterminada, los elementos de nivel de bloque se presentan en la dirección del flujo del bloque, en función del modo de escritura de los padres (initial: horizontal-tb): cada uno aparecerá en una línea nueva debajo de la última, y estarán separados por cualquier margen que se establezca en ellos. Por lo tanto, en inglés, o en cualquier otro modo de escritura horizontal y de arriba a abajo, los elementos de nivel de bloque se disponen verticalmente.

+ +

Los elementos en línea se comportan de manera diferente: no aparecen en líneas nuevas; en su lugar, se asientan en la misma línea entre sí y con cualquier contenido de texto adyacente (o envuelto), siempre que tengan espacio dentro del ancho del elemento de nivel de bloque primario. Si no hay espacio, el texto o los elementos que desborden bajarán a la línea siguiente.

+ +

Si dos elementos adyacentes tienen algún margen configurado y los dos márgenes se tocan, se mantiene el mayor de los dos y el menor desaparece; esto se llama colapso del margen, y ya lo hemos visto antes.

+ +

Echemos un vistazo a un ejemplo sencillo que explica todo esto:

+ +
+
<h1>Flujo de los documentos básicos</h1>
+
+<p>Soy un elemento básico de nivel de bloque. Mis elementos de nivel de bloque adyacentes se encuentran en líneas nuevas debajo de mí.</p>
+
+<p>Cubrimos por defecto el 100% del ancho de nuestro elemento principal, y somos tan altos como nuestro contenido secundario. Nuestro ancho y alto total es nuestro contenido + área de relleno + ancho/alto del borde.</p>
+
+<p>Estamos separados por nuestros márgenes. Debido al colapso del margen, estamos separados por el ancho de uno de nuestros márgenes, no por ambos.</p>
+
+<p>Los elementos en línea <span>como este</span> y <span>este otro</span> se ubican en la misma y la de los nodos de texto adyacentes, mientras hay espacio en la misma línea. Si un elemento en línea desborda, <span>sigue por la línea siguiente, si es posible (como la que contiene este texto)</span>, o simplemente pasa a una línea nueva, como hace esta imagen: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
+ +
body {
+  width: 500px;
+  margin: 0 auto;
+}
+
+p {
+  background: rgba(255,84,104,0.3);
+  border: 2px solid rgb(255,84,104);
+  padding: 10px;
+  margin: 10px;
+}
+
+span {
+  background: white;
+  border: 1px solid black;
+}
+
+ +

{{ EmbedLiveSample('Normal_Flow', '100%', 500) }}

+ +

Resumen

+ +

Ahora que comprendes el flujo normal y cómo el navegador presenta las cosas por defecto, continúa para comprender cómo cambiar esta pantalla predeterminada para crear el diseño que necesitas.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Introduction", "Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/css_layout/grids/index.html b/files/es/learn/css/css_layout/grids/index.html new file mode 100644 index 0000000000..d2632cba2b --- /dev/null +++ b/files/es/learn/css/css_layout/grids/index.html @@ -0,0 +1,696 @@ +--- +title: Cuadrículas +slug: Learn/CSS/CSS_layout/Grids +translation_of: Learn/CSS/CSS_layout/Grids +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout")}}
+ +

La compaginación en cuadrícula con CSS es un método de diseño de páginas web en dos dimensiones. Te permite distribuir el contenido en filas y columnas, y tiene muchas características que facilitan la creación de diseños complejos. Este artículo te proporciona todo lo que necesitas saber para comenzar con el diseño de páginas web.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (véase Introducción al HTML) y una idea de cómo funciona el CSS (véase Introducción al CSS).
Objetivo:Entender los conceptos fundamentales que hay detrás de los métodos de compaginación en cuadrícula y de cómo implementar una compaginación en cuadrícula con CSS.
+ +

¿Qué es la compaginación en cuadrícula?

+ +

Una cuadrícula es un conjunto de líneas horizontales y verticales que crean un patrón sobre el que podemos alinear nuestros elementos de diseño. Las cuadrículas nos ayudan a crear diseños de página en que los elementos no saltan ni cambian de ancho cuando nos movemos de una página a otra, y así proporcionan a nuestras páginas web un aspecto más coherente.

+ +

Una cuadrícula en general tiene columnas, filas y luego espacios entre cada fila y cada columna, conocidos comúnmente como canales.

+ +

+ +

Crear tu cuadrícula con CSS

+ +

Una vez que has decidido qué tipo de cuadrícula necesita tu diseño de página, puedes usar la compaginación en cuadrícula con CSS para crear esa cuadrícula y posicionar elementos en ella. Primero veremos las características básicas de la compaginación en cuadrícula y luego exploraremos cómo crear un método de compaginación de cuadrícula sencilla para tu proyecto.

+ +

Definir una cuadrícula

+ +

Como punto de partida, descárgate el archivo de punto de partida y ábrelo en tu editor de texto y tu navegador (también puedes verlo en vivo aquí). Hay un ejemplo con un contenedor que tiene algunos elementos hijo. Por defecto, estos se muestran en flujo normal, por lo que las cajas se muestran una debajo de la otra. Vamos a trabajar con este archivo durante la primera parte de este artículo, y vamos a hacer cambios en él para ver cómo se comporta la cuadrícula.

+ +

Para definir una cuadrícula utilizamos el valor grid de la propiedad {{cssxref ("display")}}. Al igual que con el método Flexbox, esto activa la compaginación de cuadrícula y todos los elementos que son hijos directos del contenedor se convierten en elementos de cuadrícula. Añade esto al CSS en tu archivo:

+ +
.container {
+    display: grid;
+}
+ +

A diferencia del método Flexbox, los elementos no se ven diferentes inmediatamente. La declaración display: grid te proporciona una cuadrícula de una sola columna, por lo que tus elementos continúan mostrándose uno debajo del otro, como lo hacen en el flujo normal.

+ +

Para ver algo que se parezca más a una cuadrícula, necesitamos añadir columnas a la cuadrícula. Vamos a añadir tres columnas de 200 píxeles. Puedes usar cualquier unidad de longitud o porcentajes para crear estas trazas de columna.

+ +
.container {
+    display: grid;
+    grid-template-columns: 200px 200px 200px;
+}
+ +

Añade la segunda declaración a tu regla CSS, luego vuelve a cargar la página y observa que los elementos se reubican uno en cada celda de la cuadrícula que has creado.

+ +
+ +
+ +

{{ EmbedLiveSample('Grid_1', '100%', 400) }}

+ +

Cuadrículas flexibles con la unidad fr

+ +

Además de crear cuadrículas con longitudes y porcentajes, podemos usar la unidad fr para dimensionar de manera flexible las filas y columnas de la cuadrícula. Esta unidad representa una fracción del espacio disponible en el contenedor de la cuadrícula.

+ +

Cambia tu lista de trazas en la definición siguiente para crear tres trazas 1fr.

+ +
.container {
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+}
+ +

Ahora deberías observar que tus trazas son flexibles. La unidad fr distribuye el espacio por proporciones, de modo que puedes dar valores positivos diferentes a sus trazas, por ejemplo, si cambias la definición de la manera siguiente:

+ +
.container {
+    display: grid;
+    grid-template-columns: 2fr 1fr 1fr;
+}
+ +

Ahora la primera traza tiene 2fr del espacio disponible, y las otras dos trazas tienen 1fr, lo que da una primera traza más grande. Puedes mezclar unidades fr y trazas de longitud fija; en tal caso, el espacio que se necesita para las trazas fijas se descuenta del espacio en que se distribuyen las otras trazas.

+ +
+ +
+ +

{{ EmbedLiveSample('Grid_2', '100%', 400) }}

+ +
+

Nota: La unidad fr distribuye el espacio disponible, no todo el espacio. Por lo tanto, si una de tus trazas tiene algo grande dentro, habrá menos espacio libre para compartir.

+
+ +

Los espacios entre trazas

+ +

Para crear espacios entre trazas, utilizamos las propiedades {{cssxref ("grid-column-gap")}} para los espacios entre columnas, {{cssxref ("grid-row-gap")}} para los espacios entre filas, y {{ cssxref ("grid-gap")}} para configurar ambos a la vez.

+ +
.container {
+    display: grid;
+    grid-template-columns: 2fr 1fr 1fr;
+    grid-gap: 20px;
+}
+ +

Estos espacios pueden expresarse en cualquier unidad de longitud o en porcentaje, pero no en unidades fr.

+ +
+ +
+ +

{{ EmbedLiveSample('Grid_3', '100%', 400) }}

+ +
+

Nota: Las propiedades *gap solían tener el prefijo grid-, pero esto se ha cambiado en la especificación, porque la intención es hacerlas compatibles con diversos métodos de diseño. Por el momento, Edge y Firefox admiten las versiones sin prefijo, y las versiones con prefijo se mantienen como un alias, por lo que será seguro usarlas durante algún tiempo. Para quedarte en lo seguro, y que tu código sea más a prueba de balas, puedes duplicar y añadir ambas propiedades.

+
+ +
.container {
+  display: grid;
+  grid-template-columns: 2fr 1fr 1fr;
+  grid-gap: 20px;
+  gap: 20px;
+}
+ +

Repetir listas de trazas

+ +

Puedes repetir todas tus trazas, o una sección de tu lista de trazas, con la notación de repetición. Cambia tu lista de trazas por lo siguiente:

+ +
.container {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-gap: 20px;
+}
+ +

Ahora vas a tener 3 trazas de 1fr, igual que antes. El primer valor que pasas a la función de repetición son las veces que deseas que la lista se repita, mientras que el segundo valor es una lista de trazas, que puede constar de una o más trazas.

+ +

La cuadrícula implícita y explícita

+ +

Hasta ahora solo hemos especificado trazas de columna y, sin embargo, también creamos filas para contener nuestro contenido. Este es un ejemplo de una cuadrícula explícita con respecto a una implícita. La cuadrícula explícita es la que creas usando grid-template-columns o grid-template-rows. La cuadrícula implícita se crea cuando el contenido se posiciona fuera de esa cuadrícula, como en nuestras filas. Las cuadrículas explícitas e implícitas son análogas a los ejes principales y transversales del método Flexbox.

+ +

Por defecto, las trazas que se crean en la cuadrícula implícita tienen un tamaño auto, lo que en general significa que son lo bastante grandes para ajustarse a su contenido. Si deseas asignar un tamaño a las trajas de las cuadrícula implícitas, puedes usar las propiedades {{cssxref ("grid-auto-rows")}} y {{cssxref ("grid-auto-columns")}}. Si añades grid-auto-rows con un valor de 100px a tu CSS, observa que esas filas que has creado ahora tienen 100 píxeles de alto.

+ +
+ + +
.container {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  grid-auto-rows: 100px;
+  grid-gap: 20px;
+}
+
+ +

{{ EmbedLiveSample('Grid_4', '100%', 400) }}

+ +

La función minmax()

+ +

Nuestras trazas de 100 píxeles de altura no serán muy útiles si en esas trazas añadimos contenido cuya altura sea mayor que 100 píxeles, porque ello causaría un desbordamiento. Puede ser mejor tener trazas cuya altura sea de al menos 100 píxeles y que puedan expandirse si en ellas entra más contenido. Un hecho en realidad básico sobre la web es que nunca sabes qué altura va a tener algo; contenido adicional o tamaños de letra más grandes pueden causar problemas con los diseños que pretendes ser perfectos con todas las dimensiones en píxeles.

+ +

La función minmax permite establecer unos tamaños mínimo y máximo para una traza, por ejemplo, minmax(100px, auto). El tamaño mínimo es de 100 píxeles, pero el máximo es auto, que se expande para adaptarse al contenido. Prueba a cambiar grid-auto-rows para usar un valor minmax:

+ +
.container {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-auto-rows: minmax(100px, auto);
+    grid-gap: 20px;
+}
+ +

Observa que si añades contenido la traza se expande para permitir que se ajuste. Ten en cuenta que la expansión se produce en la dirección de la fila.

+ +

Tantas columnas como quepan

+ +

Podemos combinar algunas de las cosas que hemos aprendido sobre las listas de trazas, la notación de repetición y la función minmax() para crear un patrón útil. A veces es útil poder pedirle a la cuadrícula que cree tantas columnas como quepan en el contenedor. Para hacer esto establecemos el valor grid-template-columns con la notación repeat(), pero en lugar de pasar un número, pasa la palabra clave auto-fill. Para el segundo parámetro de la función usamos minmax(), con un valor mínimo igual al tamaño mínimo de la traza que nos gustaría tener, y un valor máximo de 1fr.

+ +

Prueba esto en tu archivo ahora, con el CSS siguiente:

+ +
+ + +
.container {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+  grid-auto-rows: minmax(100px, auto);
+  grid-gap: 20px;
+}
+
+ +

{{ EmbedLiveSample('Grid_5', '100%', 400) }}

+ +

Esto funciona porque la cuadrícula crea tantas columnas de 200 píxeles como caben en el contenedor, luego comparte el espacio restante entre todas las columnas: el máximo es 1fr, que como sabemos, distribuye el espacio de manera uniforme entre las trazas.

+ +

Posicionamiento sobre las líneas de base

+ +

Ahora pasamos de crear una cuadrícula a colocar cosas en la cuadrícula. Nuestra cuadrícula siempre tiene líneas; estas líneas comienzan en 1 y se relacionan con el modo de escritura del documento. Por lo tanto, en español, la línea de columna 1 es la de la izquierda de la cuadrícula y la línea de fila 1 es la de la parte superior. En una columna arábiga, la línea 1 estaría en el lado derecho, ya que el árabe se escribe de derecha a izquierda.

+ +

Podemos posicionar los elementos de acuerdo con estas líneas si especificamos las líneas de inicio y final. Hacemos esto con las propiedades siguientes:

+ + + +

Todas estas propiedades pueden tener un número de línea como valor. También puedes usar las propiedades abreviadas:

+ + + +

Estas te permiten especificar a la vez las líneas de inicio y final, separadas por un carácter de barra diagonal: /.

+ +

Descarga este archivo de punto de partida o míralo en vivo aquí. Ya hay una cuadrícula definida y un elemento sencillo esbozado. Puedes observar que el posicionamiento automático coloca un elemento en cada celda de la cuadrícula que hemos creado.

+ +

Nosotros vamos a utilizar en lugar de ello las líneas de cuadrícula para posicionar sobre la cuadrícula todos los elementos de nuestro sitio web. Añade al final de tu código CSS las reglas siguientes:

+ +
header {
+  grid-column: 1 / 3;
+  grid-row: 1;
+}
+
+article {
+  grid-column: 2;
+  grid-row: 2;
+}
+
+aside {
+  grid-column: 1;
+  grid-row: 2;
+}
+
+footer {
+  grid-column: 1 / 3;
+  grid-row: 3;
+}
+ +
+ +
+ +

{{ EmbedLiveSample('Grid_6', '100%', 400) }}

+ +
+

Nota: también puedes usar el valor -1 para señalar la columna del final o la fila del final, y contar hacia atrás desde el final con valores negativos. Sin embargo, esto solo funciona con la cuadrícula explícita. El valor -1 no señala la línea del final de la cuadrícula implícita.

+
+ +

Posicionamiento con grid-template-areas

+ +

Una forma alternativa de posicionar elementos en tu cuadrícula es usar la propiedad {{cssxref ("grid-template-areas")}} y asignar un nombre a los diversos elementos de tu diseño.

+ +

Elimina el posicionamiento sobre las líneas de base del último ejemplo (o vuelve a descargar el archivo para tener un punto de partida nuevo) y añade el código CSS siguiente.

+ +
.container {
+  display: grid;
+  grid-template-areas:
+      "header header"
+      "sidebar content"
+      "footer footer";
+  grid-template-columns: 1fr 3fr;
+  grid-gap: 20px;
+}
+
+header {
+  grid-area: header;
+}
+
+article {
+  grid-area: content;
+}
+
+aside {
+  grid-area: sidebar;
+}
+
+footer {
+  grid-area: footer;
+}
+ +

Vuelve a cargar la página y observa que tus elementos se han colocado como antes ¡sin necesidad de usar números de línea!

+ +
+ +
+ +

{{ EmbedLiveSample('Grid_7', '100%', 400) }}

+ +

Las reglas para grid-template-areas son las siguientes:

+ + + +

Puedes jugar con nuestro diseño, por ejemplo, cambiar el pie de página para que esté solo debajo del contenido, y la barra lateral para abarcar todo. Esta manera de describir un diseño de página es muy adecuada porque resulta obvio a partir del CSS qué sucede exactamente.

+ +

Una cuadrícula CSS, formato de cuadrícula

+ +

Los «formatos» de cuadrícula tienden a basarse en cuadrículas de 12 o 16 columnas, y con las cuadrículas CSS no necesitas ninguna herramienta de terceros para proporcionarte dicho formato, porque ya está en la especificación.

+ +

Descárgate el archivo de punto de partida. Contiene un contenedor con una cuadrícula de 12 columnas definida y el mismo código de marcado que usamos en los dos ejemplos anteriores. Ahora podemos usar el posicionamiento sobre las líneas de base para colocar nuestro contenido en la cuadrícula de 12 columnas.

+ +
header {
+  grid-column: 1 / 13;
+  grid-row: 1;
+}
+
+article {
+  grid-column: 4 / 13;
+  grid-row: 2;
+}
+
+aside {
+  grid-column: 1 / 4;
+  grid-row: 2;
+}
+
+footer {
+  grid-column: 1 / 13;
+  grid-row: 3;
+}
+ +
+ +
+ +

{{ EmbedLiveSample('Grid_8', '100%', 400) }}

+ +

Si usas el inspector de cuadrícula de Firefox para ver una superposición de las líneas de cuadrícula sobre tu diseño, puedes observar cómo funciona nuestra cuadrícula de 12 columnas.

+ +

Una superposición de la cuadrícula de 12 columnas de nuestro diseño de página.

+ +

¡Pon a prueba tus conocimientos!

+ +

Has llegado al final de este artículo, pero ¿recuerdas la información más importante? Encontrarás test de prueba que te permitirán verificar que has asimilado esta información antes de continuar en: Pon a prueba tus conocimientos: Cuadrículas.

+ +

Resumen

+ +

En esta descripción general, hemos recorrido las características principales del diseño páginas web con cuadrícula CSS. Deberías poder comenzar a usarlo en tus diseños. Para profundizar en la especificación, lee nuestras guías para el diseño de página con cuadrícula, que puedes encontrar a continuación.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/css_layout/index.html b/files/es/learn/css/css_layout/index.html new file mode 100644 index 0000000000..afa1b0f9a0 --- /dev/null +++ b/files/es/learn/css/css_layout/index.html @@ -0,0 +1,87 @@ +--- +title: Diseño CSS +slug: Learn/CSS/CSS_layout +tags: + - Aprender + - CSS + - Floating + - Grids + - Guía + - Landing + - Layout + - Module + - Multiple column + - Positioning + - Principiante + - TopicStub + - flexbox + - float +translation_of: Learn/CSS/CSS_layout +--- +
{{draft}}
+ +
{{LearnSidebar}}
+ +

Llegados a este punto, hemos examinado los fundamentos básicos de CSS: cómo dar estilo al texto y cómo manipular las cajas que incluyen tu contenido. Llegó el momento de explorar cómo colocar tus cajas en el lugar que elijas con respecto a la ventana principal y el resto de cajas. Hemos cubierto ya los prerrequisitos necesarios, así que vamos a sumergirnos en la maquetación CSS, fijándonos en diferentes configuraciones de visualización, métodos de maquetación tradicionales que implican floats y posicionamiento, así como a nuevas herramientas de maquetación en voga, como flexbox.

+ +

Prerrequisitos

+ +

Antes de comenzar este módulo, ya deberías:

+ +
    +
  1. Estar familiarizado con HTML, como se expone en el módulo Introduction to HTML.
  2. +
  3. Sentirte cómodo con los fundamentos de CSS, que se discuten en   Introduction to CSS.
  4. +
  5. Entender como diseñar cajas style boxes.
  6. +
+ +
+

Nota: Si estás trabajando en un dispositivo donde no tengas la posibilidad de crear tus propios archivos, puedes probar la mayoría de los ejemplos de código en un programa online como JSBin o Thimble.

+
+ +

Guías

+ +

Estos artículos te proporcionarán instrucciones sobre las herramientas y técnicas básicas de maquetación disponibles en CSS.

+ +
+
Introducción a la maquetación CSS
+
En este artículo repasaremos algunas de las características de la maquetación con CSS que ya hemos tratado en módulos previos, como los diferentes valores de {{cssxref("display")}} ; e introduciremos algunos de los conceptos que estudiaremos a lo largo del módulo.
+
Normal flow
+
Los elementos en las páginas web se presentan de acuerdo con el flujo normal, hasta que hacemos algo que cambie eso. Este artículo explica las bases del flujo normal para aprender como cambiarlo.
+
Flexbox
+
Flexbox  es una muy reciente tecnología que, soportada ya por numerosos navegadores, está lista para su uso generalizado. Flexbox proporciona las herramientas necesarias para crear rápidamente maquetaciones flexibles y complejas, así como otras funcionalidades que tradicionalmente eran de difícil implementación con CSS. Este artículo explica su funcionamiento básico.
+
Grids
+
Los sistemas de cuadrícula son otra funcionalidad muy utilizada para la maquetación CSS, que tiende a ser implementada mediante floats u otras funciones de maquetación. Visualizas tu maquetación como un número fijo de columnas donde vas incluyendo tu contenido. En este artículo exploraremos la idea básica detrás de un sistema de cuadrícula, y terminaremos experimentando con CSS Grid, una incipiente nueva característica que permite diseñar una cuadricula Web con gran facilidad
+
Floats
+
Inicialmente utilizado para imágenes flotantes dentro de bloques de texto, la propiedad {{cssxref("float")}} se ha convertido en una de las herramientas más utilizadas para crear maquetaciones de varias columnas en páginas web. Con la venida de Flexbox y Grid se ha regresado a su propósito original, como lo explica este artículo.
+
Posicionamiento
+
El posicionamiento te permite sacar elementos del flujo normal de maquetación del documento para hacer que se comporten de manera diferente, p.ej: colocando unos encima de otros, o fijándolos a un lugar de la ventana principal. Este artículo explica los diferentes valores para  {{cssxref("position")}} y cómo utilizarlos.
+
Ejemplos prácticos de posicionamiento
+
Una vez cubiertas las nociones básicas de posicionamiento en el artículo anterior, vamos ahora a construir un par de ejemplos reales, para explicar las cosas que puedes hacer con el posicionamiento.
+
Diseño Multi-columna
+
El diseño multi-columna te proporciona un método de maquetación de contenido en columnas, como lo podrías ver en un periódico. Este artículo explica como usar esta característica.
+
Responsive design
+
A medida que han aparecido diversos tamaños de pantalla en dispositivos habilitados para la web, apareció un conjunto de practicas que permiten a las páginas web alterar su diseño y apariencia para adaptarse a diferentes anchos de pantalla, resoluciones, etc.Este se conoce como Responsive design (RWD) y es una idea que cambió la forma en que diseñamos páginas web multi-dispositivos, y en este artículo te ayudaremos a entender las principales técnicas que necesitas saber para dominarlo.
+
Guía de consulta de medios para principiantes
+
CSS Media Query te proporciona una forma de aplicar CSS solo cuando el entorno del navegador y el dispositivo coincide con las reglas que especificaste, por ejemplo "la ventana principal es más ancha de 480 pixels". Las consultas de medios son una parte clave del responsive web design, ya que te permiten crear diferentes diseños dependiendo del tamaño de la ventana principal, así como también puede ser usado para detectar otras cosas acerca del entorno en donde tu página web se está ejecutando, por ejemplo si el usuario está usando una pantalla táctil en lugar de un ratón. En esta guía, aprenderás primero acerca de la sintaxis usada en las consultas de medios, y luego pasar a usarlos en un ejemplo donde se muestra cómo un diseño simple puede hacerse responsive.
+
Métodos de diseño heredados
+
Los sistemas Grid son una característica muy común usada en el diseño CSS, y antes del diseño Grid CSS, tendían a ser implementados usando floats u otras características de diseño. Imagina tu diseño como un conjunto de números de columnas (p.ej. 4, 5 o 12), y luego acomoda tus columnas de contenido dentro de esas columnas imaginarias. En este artículo vamos a explorar cómo funcionan estos métodos para que entiendas como eran usados si trabajas en un proyecto más antiguo. 
+
Soporte a navegadores antiguos
+
En este modulo recomendamos usar Flexbox y Grid como principal método de diseño. Siempre habrán personas que visiten tu página web desde navegadores antiguos, o navegadores que no soportan los métodos que usaste. Este siempre ha sido el caso en la web: a medida que se desarrollan nuevas características, los distintos navegadores priorizan diferentes cosas. Este artículo explica como usar técnicas modernas para la web sin dejar por fuera a los usuarios de tecnologías antiguas. 
+
+ +

Ejercicios

+ +

Los siguientes ejercicios comprobarán tu habilidad para maquetar páginas web con CSS.

+ +
+
Creando una maquetación de varias columnas flexibles
+
Este ejercicio comprobará tu habilidad par crear una maquetación multi-columna, con alguna que otra característica interesante.
+
Creando un widget fijo de control
+
Este ejercicio pone a prueba tu entendimiento sobre el posicionamiento, proponiéndote crear un widget de control con posición fija, que permitirá al usuario acceder a los controles de una aplicación Web, independientemente de dónde se hubiera desplazado en la página.
+
+ +

Ver también

+ + diff --git "a/files/es/learn/css/css_layout/introducci\303\263n/index.html" "b/files/es/learn/css/css_layout/introducci\303\263n/index.html" new file mode 100644 index 0000000000..2f409d97c3 --- /dev/null +++ "b/files/es/learn/css/css_layout/introducci\303\263n/index.html" @@ -0,0 +1,701 @@ +--- +title: Introducción al diseño en CSS +slug: Learn/CSS/CSS_layout/Introducción +translation_of: Learn/CSS/CSS_layout/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/CSS/CSS_layout/Normal_Flow", "Learn/CSS/CSS_layout")}}
+ +

Este artículo resumirá algunas de las características de diseño de páginas web con CSS que ya hemos mencionado en módulos anteriores, como los diferentes valores de {{cssxref ("display")}}, e introducirá algunos de los conceptos que vamos a tratar en este módulo.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Introducción al CSS).
Objetivo:Proporcionar una visión general de las técnicas de diseño de páginas web con CSS. Cada técnica se puede aprender con mayor detalle en tutoriales posteriores.
+ +

Las técnicas de diseño de páginas web con CSS nos permiten controlar dónde se ubican los elementos que están contenidos en una página web en relación con su posición predeterminada en el flujo de diseño normal, así como el resto de elementos a su alrededor, su contenedor principal o la vista/ventana principal. Las técnicas de diseño de páginas web que trataremos con más detalle en este módulo son:

+ + + +

Cada técnica tiene sus usos, ventajas y desventajas, y ninguna técnica está diseñada para usarse de forma aislada. Si entiendes para qué se ha diseñado cada método, te será fácil comprender cuál es la mejor herramienta de diseño para cada tarea.

+ +

Flujo normal

+ +

El flujo normal es el modo como el navegador presenta las páginas HTML de forma predeterminada cuando no haces nada para controlar el diseño de página. Echemos un vistazo rápido a un ejemplo HTML:

+ +
<p>Amo a mi gato.</p>
+
+<ul>
+  <li>Comprar comida para gatos</li>
+  <li>Ejercicio</li>
+  <li>Anímate amigo</li>
+</ul>
+
+<p>¡Fin!</p>
+ +

Por defecto, el navegador mostrará este código de la manera siguiente:

+ +

{{ EmbedLiveSample('Normal_flow', '100%', 200) }}

+ +

Observa aquí cómo se muestra el HTML en el orden exacto en que aparece en el código fuente, con los elementos uno debajo del otro: el primer párrafo, seguido de la lista desordenada, y a continuación el segundo párrafo.

+ +

Los elementos que aparecen uno debajo del otro se describen como elementos de bloque, en contraposición con los elementos de línea, que aparecen uno al lado del otro, como las palabras de un párrafo.

+ +
+

Nota: La dirección en la que se presentan los contenidos de un elemento de bloque se describe como dirección de los bloques. La dirección de los bloques va de arriba a abajo en un idioma como el español, cuyo modo de escritura es horizontal. Sería horizontal en cualquier idioma con un modo de escritura vertical, como el japonés. Correspondientemente, la dirección de línea es la dirección en la que los contenidos de línea (por ejemplo, una frase) se disponen.

+
+ +

Cuando usas CSS para crear un diseño de página web, alejas los elementos del flujo normal, pero para muchos de los elementos de tu página, el flujo normal proporciona exactamente el diseño que necesitas. Por esta razón resulta tan importante comenzar con un documento HTML bien estructurado, porque te permite trabajar ya con la forma en que las cosas se presentan por defecto, en lugar de tener que luchar contra ello.

+ +

Los métodos que permiten cambiar la disposición de los elementos en CSS son los siguientes:

+ + + +

La propiedad display

+ +

Los métodos principales para lograr el diseño de páginas web con CSS son todos los valores de la propiedad display. Esta propiedad permite cambiar la forma predeterminada en que algo se muestra. Todo en flujo normal tiene un valor de display, utilizado como la forma como se comportan por defecto los elementos en los que están configurados. Por ejemplo, el hecho de que los párrafos en español se muestran uno debajo del otro se debe a que presentan la configuración display: block. Si creas un enlace alrededor de un texto dentro de un párrafo, ese enlace permanece en línea con el resto del texto y no se divide al pasar a una línea nueva. Esto se debe a que el elemento {{htmlelement ("a")}} es por defecto display: inline.

+ +

Puedes cambiar este comportamiento predeterminado de visualización (display). Por ejemplo, el elemento {{htmlelement ("li")}} es display: block de forma predeterminada, lo que significa que los elementos de la lista se muestran uno debajo del otro en nuestro documento en español. Si cambiamos el valor de visualización a inline, ahora se muestran uno al lado del otro, como lo harían las palabras de una frase. El hecho de que puedas cambiar el valor de display de cualquier elemento significa que puedes elegir elementos HTML por su significado semántico, sin preocuparte por cómo se verán. La forma en que se ven es algo que puedes cambiar.

+ +

Además de poder cambiar la presentación predeterminada de un elemento block a un elemento inline y viceversa, hay algunos métodos de diseño de página más poderosos que se inician como un valor de display. Sin embargo, cuando los uses, en general vas a necesitar propiedades adicionales. Los dos valores más importantes para nuestros propósitos cuando hablamos del diseño de páginas web son display: flex y display: grid.

+ +

Flexbox

+ +

Flexbox es el nombre corto del módulo de diseño de cajas flexibles, pensado para facilitarnos la distribución de las cosas en una dimensión, ya sea como una fila o como una columna. Para usar el método Flexbox, aplica display: flex al elemento padre de los elementos que deseas distribuir; todos sus elementos hijo directos se convierten en elementos flexibles. Vamos a verlo en un ejemplo sencillo.

+ +

El marcado HTML siguiente nos proporciona un elemento contenedor con una clase wrapper dentro del cual hay tres elementos {{htmlelement ("div")}}. Por defecto, estos elementos se mostrarían como elementos de bloque, uno debajo del otro, en nuestro documento en español.

+ +

Sin embargo, si añadimos display: flex al elemento padre, los tres elementos se organizan en columnas. Esto se debe a que se convierten en elementos flexibles y se ven afectados por algunos valores iniciales que el método Flexbox establece en el contenedor flexible. Se muestran en una fila porque el valor inicial de {{cssxref ("flex-direction")}} establecido en su elemento padre es row. Todos parecen expandirse hasta la altura del elemento de más altura, porque el valor inicial de la propiedad {{cssxref ("align-items")}} establecida en su elemento primario es stretch. Esto significa que los artículos se expanden hasta la altura del contenedor flexible, que en este caso está definida por el artículo de mayor altura. Todos los artículos se alinean al comienzo del contenedor y dejan el espacio que sobra al final de la fila.

+ +
+ + +
.wrapper {
+  display: flex;
+}
+
+ +
<div class="wrapper">
+  <div class="box1">Uno</div>
+  <div class="box2">Dos</div>
+  <div class="box3">Tres</div>
+</div>
+
+
+ +

{{ EmbedLiveSample('Flex_1', '300', '200') }}

+ +

Además de las propiedades anteriores, que pueden aplicarse a contenedores flexibles, también hay propiedades que pueden aplicarse a los elementos flexibles. Estas propiedades, entre otras cosas, pueden cambiar el comportamiento de estos elementos flexibles y permitirles expandirse y contraerse para adaptarse al espacio disponible.

+ +

Como un ejemplo sencillo de esto podemos añadir la propiedad {{cssxref ("flex")}} a todos nuestros elementos secundarios, con un valor de 1. Esto hará que todos los elementos crezcan y llenen el contenedor, en lugar de dejar espacio al final. Si hay más espacio, los artículos se ensancharán; si hay menos espacio, se volverán más estrechos. Además, si añades al código otro elemento, todos los elementos se volverán más pequeños para dejarle espacio; ajustarán el tamaño para ocupar la misma cantidad de espacio, cualquiera que sea.

+ +
+ + +
.wrapper {
+    display: flex;
+}
+
+.wrapper > div {
+    flex: 1;
+}
+
+ +
<div class="wrapper">
+    <div class="box1">Uno</div>
+    <div class="box2">Dos</div>
+    <div class="box3">Tres</div>
+</div>
+
+
+ +

{{ EmbedLiveSample('Flex_2', '300', '200') }}

+ +
+

Nota: Esta ha sido una breve introducción de lo que permite el método Flexbox. Para obtener más información, consulta nuestro artículo sobre Flexbox.

+
+ +

Diseño de cuadrícula

+ +

Mientras que el método Flexbox está pensado para distribuir elementos unidimensionalmente, el diseño de cuadrícula está diseñado para distribuir elementos en dos dimensiones: alinear elementos en filas y columnas.

+ +

Una vez más, puedes activar el diseño de páginas web en cuadrícula con un valor de visualización específico: display: grid. El ejemplo siguiente utiliza un marcado similar al del ejemplo del método Flexbox, con un contenedor y algunos elementos secundarios. Además de usar display: grid, también definimos algunos tramos de filas y columnas en el elemento padre con las propiedades {{cssxref("grid-template-rows")}} y {{cssxref("grid-template-columns")}}. Hemos definido tres columnas, cada una de 1fr, y dos filas de 100px. No necesitamos poner ninguna regla sobre los elementos secundarios porque se colocan automáticamente en las celdas que nuestra cuadrícula ha creado.

+ +
+ + +
.wrapper {
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    grid-template-rows: 100px 100px;
+    grid-gap: 10px;
+}
+
+ +
<div class="wrapper">
+    <div class="box1">Uno</div>
+    <div class="box2">Dos</div>
+    <div class="box3">Tres</div>
+    <div class="box4">Cuatro</div>
+    <div class="box5">Cinco</div>
+    <div class="box6">Seis</div>
+</div>
+
+
+ +

{{ EmbedLiveSample('Grid_1', '300', '330') }}

+ +

Cuando ya tienes una cuadrícula, se puede colocar tus elementos en ella explícitamente en lugar de confiar en el comportamiento de colocación automática que hemos visto arriba. En el segundo ejemplo, hemos definido la misma cuadrícula, pero esta vez con tres elementos secundarios. Hemos establecido la línea de inicio y final de cada elemento con las propiedades {{cssxref ("grid-column")}} y {{cssxref ("grid-row")}}. Esto hace que los elementos abarquen varios tramos.

+ +
+ + +
.wrapper {
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    grid-template-rows: 100px 100px;
+    grid-gap: 10px;
+}
+
+.box1 {
+    grid-column: 2 / 4;
+    grid-row: 1;
+}
+
+.box2 {
+    grid-column: 1;
+    grid-row: 1 / 3;
+}
+
+.box3 {
+    grid-row: 2;
+    grid-column: 3;
+}
+
+ +
<div class="wrapper">
+    <div class="box1">Uno</div>
+    <div class="box2">Dos</div>
+    <div class="box3">Tres</div>
+</div>
+
+
+ +

{{ EmbedLiveSample('Grid_2', '300', '330') }}

+ +
+

Nota: Estos dos ejemplos son solo una pequeña parte del poder del diseño de cuadrículas; para obtener más información, consulta nuestro artículo sobre Diseñar cuadrículas.

+
+ +

El resto de esta guía expone otros métodos de diseño de páginas web que son menos importantes para las estructuras principales de diseño de tu página web, pero que pueden serte de ayuda para tareas específicas. Si entiendes la naturaleza de cada una de las tareas de diseño de una página web, vas a descubrir enseguida que a menudo vas a ser capaz de discernir qué tipo de diseño se adapta mejor a cada componente de tu diseño particular.

+ +

Floats

+ +

El método de flotación de un elemento cambia el comportamiento de ese elemento y de los elementos de nivel de bloque que lo siguen en el flujo normal. El elemento es desplazado hacia la izquierda o hacia la derecha y es eliminado del flujo normal, y el contenido circundante flota alrededor de este elemento.

+ +

La propiedad {{cssxref ("float")}} tiene cuatro valores posibles:

+ + + +

En el ejemplo siguiente, establecemos una flotación a la izquierda para un elemento <div> y le damos un {{cssxref ("margin")}} a la derecha para mantener el texto alejado del elemento. Esto nos da el efecto del texto envuelto alrededor de ese cuadro, y es la mayor parte de lo que necesitas saber sobre la flotación, tal como se utiliza en el diseño web moderno.

+ +
+ + +
<h1>Ejemplo sencillo de flotación</h1>
+
+<div class="box">Float</div>
+
+<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>
+
+
+ +
+.box {
+    float: left;
+    width: 150px;
+    height: 150px;
+    margin-right: 30px;
+}
+
+
+ +

{{ EmbedLiveSample('Float_1', '100%', 600) }}

+ +
+

Nota: El método de flotación se explica al completo en nuestro artículo sobre las propiedades float y clear. El método de flotación es el que se usaba para crear diseños de columnas antes de la aparición de técnicas como los métodos Flexbox y diseño en rejillas. En la red aún puedes toparte con estos métodos. Vamos a exponer todo esto en el artículo sobre métodos de diseño heredados.

+
+ +

Técnicas de posicionamiento

+ +

El posicionamiento permite mover un elemento desde donde se colocaría cuando está en flujo normal a otra ubicación. El posicionamiento no es un método para crear diseños de página principal, se trata más bien de administrar y ajustar la posición de elementos específicos en la página.

+ +

Sin embargo, hay técnicas útiles para ciertos patrones de diseños de páginas web que se basan en la propiedad {{cssxref ("position")}}. Comprender el posicionamiento también ayuda a comprender el flujo normal y qué implica sacar un elemento del flujo normal.

+ +

Hay cinco tipos de posicionamiento que debes conocer:

+ + + +

Ejemplo sencillo de posicionamiento

+ +

Para familiarizarte con estas técnicas de diseño de página, te mostraremos un par de ejemplos rápidos. Todos nuestros ejemplos contarán con el mismo HTML, que es el siguiente:

+ +
<h1>Posicionamiento</h1>
+
+<p>Soy un elemento básico de nivel de bloque.</p>
+<p class="positioned">Soy un elemento básico de nivel de bloque.</p>
+<p>Soy un elemento básico de nivel de bloque.</p>
+ +

Aplicaremos a este HTML un estilo predeterminado definido por el CSS siguiente:

+ +
body {
+  width: 500px;
+  margin: 0 auto;
+}
+
+p {
+    background-color: rgb(207,232,220);
+    border: 2px solid rgb(79,185,227);
+    padding: 10px;
+    margin: 10px;
+    border-radius: 5px;
+}
+
+ +

La salida que se obtiene es la siguiente:

+ +

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

+ +

El posicionamiento relativo

+ +

El posicionamiento relativo permite compensar un elemento desde la posición por defecto que tendría en flujo normal. Esto significa que podrías hacer una tarea como mover un icono un poco hacia abajo para que se alinee con una etiqueta de texto. Para ello, podríamos añadir la regla de posicionamiento relativo siguiente:

+ +
.positioned {
+  position: relative;
+  top: 30px;
+  left: 30px;
+}
+ +

Aquí asignamos el valor relative a la propiedad {{cssxref ("position")}} de nuestro párrafo del medio: esto no hace nada por sí solo, así que también añadimos las propiedades {{cssxref ("top")}} y {{cssxref ( "left")}}, que sirven para mover el elemento afectado hacia abajo y a la derecha. Esto puede parecer lo contrario de lo que esperabas, pero debes pensar en ello como un elemento al que se empuja por sus lados superior e izquierdo, lo que resulta en un movimiento a la derecha y abajo.

+ +

Añadir este código dará el resultado siguiente:

+ +
+ + +
.positioned {
+  position: relative;
+  background: rgba(255,84,104,.3);
+  border: 2px solid rgb(255,84,104);
+  top: 30px;
+  left: 30px;
+}
+
+ +

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

+ +

El posicionamiento absoluto

+ +

El posicionamiento absoluto se utiliza para eliminar por completo un elemento del flujo normal y colocarlo mediante desplazamientos desde los bordes de un bloque contenedor.

+ +

Volviendo a nuestro ejemplo original no posicionado, podríamos añadir la regla CSS siguiente para implementar el posicionamiento absoluto:

+ +
.positioned {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+}
+ +

Aquí le damos a la propiedad {{cssxref ("position")}} de nuestro párrafo del medio un valor de absolute, y le asignamos las mismas propiedades {{cssxref ("top")}} y {{cssxref ("left")}}. Sin embargo, ahora añadir este código da el resultado siguiente:

+ +
+ + +
.positioned {
+    position: absolute;
+    background: rgba(255,84,104,.3);
+    border: 2px solid rgb(255,84,104);
+    top: 30px;
+    left: 30px;
+}
+
+ +

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

+ +

¡Este resultado es muy diferente! El elemento posicionado ahora se ha separado por completo del resto del diseño de la página y se superpone encima de este. Los otros dos párrafos ahora se asientan juntos, como si su hermano con posicionamiento absoluto no existiera. Las propiedades {{cssxref ("top")}} y {{cssxref ("left")}} tienen un efecto diferente en elementos con posicionamiento absoluto que en elementos con posicionamiento relativo. En este caso, los desplazamientos se han calculado desde la parte superior e izquierda de la página. Es posible cambiar el elemento padre para que se convierta en este tipo de contenedor, y lo veremos en el artículo sobre posicionamiento.

+ +

Posicionamiento fijo

+ +

El posicionamiento fijo elimina nuestro elemento del flujo de documentos de la misma manera que el posicionamiento absoluto. Sin embargo, en lugar de contar los desplazamientos en relación con el contenedor, se cuentan con respecto a la ventana gráfica. Como el elemento permanece fijo en relación con la ventana gráfica, podemos crear efectos como un menú que permanece fijo mientras la página se desplaza por debajo de él.

+ +

En este ejemplo nuestro HTML tiene tres párrafos de texto para poder tener una página que se desplace, y un cuadro al que asignamos la propiedad position: fixed.

+ +
<h1>Posicionamiento fijo</h1>
+
+<div class="positioned">Fijo</div>
+
+<p>Párrafo 1.</p>
+<p>Párrafo 2.</p>
+<p>Párrafo 3.</p>
+
+ +
+ + +
.positioned {
+    position: fixed;
+    top: 30px;
+    left: 30px;
+}
+
+ +

{{ EmbedLiveSample('Fixed_1', '100%', 200) }}

+ +

Posicionamiento pegajoso

+ +

El posicionamiento pegajoso es el último método de posicionamiento que tenemos a nuestra disposición. Mezcla el posicionamiento estático predeterminado con el posicionamiento fijo. Cuando un elemento tiene la propiedad position: sticky, se desplaza en flujo normal hasta que se alcanzan los desplazamientos con respecto a la ventana gráfica que hemos definido. En ese punto se queda «atascado» como si tuviera configurado un valor position: fixed.

+ +
+ + +
.positioned {
+  position: sticky;
+  top: 30px;
+  left: 30px;
+}
+
+ +

{{ EmbedLiveSample('Sticky_1', '100%', 200) }}

+ +
+

Nota: para obtener más información sobre el posicionamiento, consulta nuestro artículo Posicionamiento.

+
+ +

Diseño de tablas

+ +

Las tablas HTML sirven para mostrar datos tabulados, pero hace muchos años, antes incluso de que el CSS básico fuera compatible de forma fiable en todos los navegadores, los desarrolladores web también usaban tablas para hacer el diseño completo de una página web, colocando en las diversas filas y columnas de una tabla los títulos de encabezado de la página, los pies de página, las diferentes columnas, etc. Esto funcionó en ese momento, pero presenta muchos problemas: los diseños de tabla no son flexibles, requieren mucho código de marcado, son difíciles de depurar y no son semánticamente correctos (por ejemplo, los usuarios de lectores de pantalla tienen problemas para navegar por estos diseños de página web con tablas).

+ +

El aspecto que presenta una tabla en una página web cuando usas el código de marcado de una tabla se debe a un conjunto de propiedades CSS que definen el diseño de la tabla. Estas propiedades se pueden usar para diseñar elementos que no son tablas, un uso que a veces se describe como «usar tablas CSS».

+ +

El ejemplo siguiente muestra uno de esos usos; el uso de tablas CSS para el diseño debe considerarse en este punto un método heredado, para aquellas situaciones en las que tienes navegadores muy antiguos que no son compatibles con los métodos Flexbox o Grid.

+ +

Veamos un ejemplo. Primero, un código de marcado sencillo que crea un formulario HTML. Cada elemento de entrada tiene una etiqueta, y también hemos incluido un título dentro de un párrafo. Cada par etiqueta/entrada está delimitado por un elemento {{htmlelement ("div")}}, con fines de compaginación.

+ +
<form>
+  <p>En primer lugar, díganos su nombre y edad.</p>
+  <div>
+    <label for="fname">Nombre:</label>
+    <input type="text" id="fname">
+  </div>
+  <div>
+    <label for="lname">Apellidos:</label>
+    <input type="text" id="lname">
+  </div>
+  <div>
+    <label for="age">Edad:</label>
+    <input type="text" id="age">
+  </div>
+</form>
+ +

Ahora, el CSS para nuestro ejemplo. La mayor parte del CSS es bastante común, excepto por los usos de la propiedad {{cssxref ("display")}}. A los elementos {{htmlelement ("form")}}, {{htmlelement ("div")}}, {{htmlelement ("label")}} y {{htmlelement ("input")}} se les dice que se muestren como una tabla, filas de tabla y celdas de tabla, respectivamente; actuarán básicamente como marcas de tabla HTML, y lograrán por defecto la alineación perfecta de las etiquetas y las entradas. Todo lo que hay que hacer es añadir un poco de tamaños, márgenes, etc., para que todo se vea un poco mejor, ¡y listo!

+ +

Observa que se la ha proporcionado al párrafo de encabezado display: table-caption;, lo que hace que actúe como una celda de encabezado ({{htmlelement ("caption")}}) de la tabla; y con caption-side: bottom; se le dice a la celda de encabezado que se asiente en la parte inferior de la tabla con fines de aplicación de estilo, aunque en el código fuente el marcado está antes que los elementos <input>. Esto permite un poco de flexibilidad.

+ +
html {
+  font-family: sans-serif;
+}
+
+form {
+  display: table;
+  margin: 0 auto;
+}
+
+form div {
+  display: table-row;
+}
+
+form label, form input {
+  display: table-cell;
+  margin-bottom: 10px;
+}
+
+form label {
+  width: 200px;
+  padding-right: 5%;
+  text-align: right;
+}
+
+form input {
+  width: 300px;
+}
+
+form p {
+  display: table-caption;
+  caption-side: bottom;
+  width: 300px;
+  color: #999;
+  font-style: italic;
+}
+ +

Esto nos da el resultado siguiente:

+ +

{{ EmbedLiveSample('Table_layout', '100%', '170') }}

+ +

También puedes ver este ejemplo en vivo en css-tables-example.html (ver el código fuente).

+ +

Diseño en columnas

+ +

El módulo de diseño en columnas nos proporciona un modo de distribuir el contenido en columnas, de forma similar al modo como el texto fluye en un periódico. Aunque en un contexto web leer en columnas de arriba a abajo no resulta tan útil porque podría obligar a los usuarios a tener que hacer desplazamientos de arriba a abajo, la técnica de organizar el contenido en columnas también puede tener su utilidad.

+ +

Para convertir un bloque en un contenedor, utilizamos la propiedad {{cssxref ("column-count")}}, que le dice al navegador cuántas columnas nos gustaría tener, o {{cssxref ("column-width")}}, que le dice al navegador que llene el contenedor con tantas columnas de al menos ese ancho.

+ +

En el ejemplo siguiente comenzamos con un bloque de HTML dentro de un elemento <div> que contiene una clase container.

+ +
<div class="container">
+    <H1>Diseño en columnas</ h1>
+
+    <p>Párrafo 1.</p>
+    <p>Párrafo 2.</p>
+
+</div>
+
+ +

Utilizamos un column-width de 200 píxeles en ese contenedor, que crea en el navegador tantas columnas de 200 píxeles como quepan en el contenedor y luego comparte el espacio restante entre las columnas creadas.

+ +
+ + +
    .container {
+        column-width: 200px;
+    }
+
+ +

{{ EmbedLiveSample('Multicol_1', '100%', 200) }}

+ +

Resumen

+ +

Este artículo ha proporcionado un breve resumen de todas las tecnologías de diseño que debes conocer. ¡Sigue leyendo para obtener más información sobre cada tecnología individual!

+ +

{{NextMenu("Learn/CSS/CSS_layout/Normal_Flow", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/css_layout/positioning/index.html b/files/es/learn/css/css_layout/positioning/index.html new file mode 100644 index 0000000000..3deb33b91f --- /dev/null +++ b/files/es/learn/css/css_layout/positioning/index.html @@ -0,0 +1,469 @@ +--- +title: Positioning +slug: Learn/CSS/CSS_layout/Positioning +translation_of: Learn/CSS/CSS_layout/Positioning +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}
+ +

El posicionamiento permite sacar elementos del flujo normal del diseño del documento, y hacer que se comporten de manera distinta, por ejemplo sentarse encima de otro o permanecer en el mismo lugar dentro de la ventana navegador. Este artículo explica los diferentes valores {{cssxref("position")}}, y como usarlos.

+ + + + + + + + + + + + +
Requisitos:HTML básico (Aprende  Introducción a HTML), y una idea de cómo trabaja CSS (Aprende  Introducción a CSS.)
Objetivos:Entender como trabajar con posicionamiento CSS.
+ +

Flujo del Documento

+ +

El posicionamiento es un tema bastante complejo, así que antes de profundizar en el código volvamos a examinar y ampliar un poco la teoría del diseño para darnos una idea de cómo funciona esto.

+ +

First of all, individual element boxes are laid out by taking the elements' content, then adding any padding, border and margin around them — it's that box model thing again, which we looked at earlier. By default, a block level element's content is 100% of the width of its parent element, and as tall as its content. Inline elements are all tall as their content, and as wide as their content. You can't set width or height on inline elements — they just sit inside the content of block level elements. If you want to control the size of an inline element in this manner, you need to set it to behave like a block level element with display: block;.

+ +

That explains individual elements, but what about how elements interact with one another? The normal layout flow (mentioned in the layout introduction article) is the system by which elements are placed inside the browser's viewport. By default, block level elements are laid out vertically in the viewport — each one will appear on a new line below the last one, and they will be separated by any margin that is set on them.

+ +

Inline elements behave differently — they don't appear on new lines; instead, they sit on the same line as one another and any adjacent (or wrapped) text content, as long as there is space for them to do so inside the width of the parent block level element. If there isn't space, then the overflowing text or elements will move down to a new line.

+ +

If two adjacent elements both have margin set on them and the two margins touch, the larger of the two remains, and the smaller one disappears — this is called margin collapsing, and we have met this before too.

+ +

Let's look at a simple example that explains all this:

+ +
<h1>Basic document flow</h1>
+
+<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
+
+<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
+
+<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
+
+<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
+ +
body {
+  width: 500px;
+  margin: 0 auto;
+}
+
+p {
+  background: aqua;
+  border: 3px solid blue;
+  padding: 10px;
+  margin: 10px;
+}
+
+span {
+  background: red;
+  border: 1px solid black;
+}
+ +

{{ EmbedLiveSample('Document_flow', '100%', 500) }}

+ +

We will be revisiting this example a number of times as we go through this article, as we show the effects of the different positioning options available to us.

+ +

We'd like you to follow along with the exercises on your local computer, if possible — grab a copy of 0_basic-flow.html from our Github repo (source code here) and use that as a starting point.

+ +

Introducing positioning

+ +

The whole idea of positioning is to allow us to override the basic document flow behaviour described above, to produce interesting effects. What if you want to slightly alter the position of some boxes inside a layout from their default layout flow position, to give a slightly quirky, distressed feel? Positioning is your tool. Or if you want to create a UI element that floats over the top of other parts of the page, and/or always sits in the same place inside the browser window no matter how much the page is scrolled? Positioning makes such layout work possible.

+ +

There are a number of different types of positioning that you can put into effect on HTML elements. To make a specific type of positioning active on an element, we use the {{cssxref("position")}} property.

+ +

Static positioning

+ +

Static positioning is the default that every element gets — it just means "put the element into its normal position in the document layout flow — nothing special to see here."

+ +

To demonstrate this, and get your example set up for future sections, first add a class of positioned to the second {{htmlelement("p")}} in the HTML:

+ +
<p class="positioned"> ... </p>
+ +

Now add the following rule to the bottom of your CSS:

+ +
.positioned {
+  position: static;
+  background: yellow;
+}
+ +

If you now save and refresh, you'll see no difference at all, except for the updated background color of the 2nd paragraph. This is fine — as we said before, static positioning is the default behaviour!

+ +
+

Note: You can see the example at this point live at 1_static-positioning.html (see source code).

+
+ +

Relative positioning

+ +

Relative positioning is the first position type we'll take a look at. This is very similar to static positioning, except that once the positioned element has taken its place in the normal layout flow, you can then modify its final position, including making it overlap other elements on the page. Go ahead and update the position declaration in your code:

+ +
position: relative;
+ +

If you save and refresh at this stage, you won't see a change in the result at all — so how do you modify the element's position? You need to use the {{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, and {{cssxref("right")}} properties, which we'll explain in the next section.

+ +

Introducing top, bottom, left, and right

+ +

{{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, and {{cssxref("right")}} are used alongside {{cssxref("position")}} to specify exactly where to move the positioned element to. To try this out, add the following declarations to the .positioned rule in your CSS:

+ +
top: 30px;
+left: 30px;
+ +
+

Note: The values of these properties can take any units you'd logically expect — pixels, mm, rems, %, etc.

+
+ +

If you now save and refresh, you'll get a result something like this:

+ + + +

{{ EmbedLiveSample('Introducing_top_bottom_left_and_right', '100%', 500) }}

+ +

Cool, huh? Ok, so this probably wasn't what you were expecting — why has it moved to the bottom and right if we specified top and left? Illogical as it may initially sound, this is just the way that relative positioning works — you need to think of an invisible force that pushes the side of the positioned box, moving it in the opposite direction. So for example, if you specify top: 30px;, a force pushes the top of the box, causing it to move downwards by 30px.

+ +
+

Note: You can see the example at this point live at 2_relative-positioning.html (see source code).

+
+ +

Absolute positioning

+ +

Absolute positioning brings very different results. Let's try changing the position declaration in your code as follows:

+ +
position: absolute;
+ +

If you now save and refresh, you should see something like so:

+ + + +

{{ EmbedLiveSample('Absolute_positioning', '100%', 420) }}

+ +

First of all, note that the gap where the positioned element should be in the document flow is no longer there — the first and third elements have closed together like it no longer exists! Well, in a way, this is true. An absolutely positioned element no longer exists in the normal document layout flow. Instead, it sits on its own layer separate from everything else. This is very useful — it means that we can create isolated UI features that don't interfere with the position of other elements on the page — for example popup information boxes and control menus, rollover panels, UI features that can be dragged and dropped anywhere on the page, and so on.

+ +

Second, notice that the position of the element has changed — this is because {{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, and {{cssxref("right")}} behave in a different way with absolute positioning. Instead of specifying the direction the element should move in, they specify the distance the element should be from each containing element's sides. So in this case, we are saying that the absolutely positioned element should sit 30px from the top of the "containing element", and 30px from the left.

+ +
+

Note: You can use {{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, and {{cssxref("right")}} to resize elements if you need to. Try setting top: 0; bottom: 0; left: 0; right: 0; and margin: 0; on your positioned elements and see what happens! Put it back again afterwards...

+
+ +
+

Note: Yes, margins still affect positioned elements. Margin collapsing doesn't, however.

+
+ +
+

Note: You can see the example at this point live at 3_absolute-positioning.html (see source code).

+
+ +

Positioning contexts

+ +

Which element is the "containing element" of an absolutely positioned element? By default, it is the {{htmlelement("html")}} element — the positioned element is nested inside the {{htmlelement("body")}} in the HTML source, but in the final layout, it is 30px away from the top and left of the edge of the page, which is the {{htmlelement("html")}} element. This is more accurately called the element's positioning context.

+ +

We can change the positioning context — which element the absolutely positioned element is positioned relative to. This is done by setting positioning on one of the element's other ancestors — one of the elements it is nested inside (you can't position it relative to an element it is not nested inside). To demonstrate this, add the following declaration to your body rule:

+ +
position: relative;
+ +

This should give the following result:

+ + + +

{{ EmbedLiveSample('Positioning_contexts', '100%', 420) }}

+ +

The positioned element now sits relative to the {{htmlelement("body")}} element.

+ +
+

Note: You can see the example at this point live at 4_positioning-context.html (see source code).

+
+ +

Introducing z-index

+ +

All this absolute positioning is good fun, but there is another thing we haven't considered yet — when elements start to overlap, what determines which elements appear on top of which other elements? In the example we've seen so far, we only have one positioned element in the positioning context, and it appears on the top, since positioned elements win over non-positioned elements. What about when we have more than one?

+ +

Try adding the following to your CSS, to make the first paragraph absolutely positioned too:

+ +
p:nth-of-type(1) {
+  position: absolute;
+  background: lime;
+  top: 10px;
+  right: 30px;
+}
+ +

At this point you'll see the first paragraph colored green, moved out of the document flow, and positioned a bit above from where it originally was. It is also stacked below the original .positioned paragraph, where the two overlap. This is because the .positioned paragraph is the second paragraph in the source order, and positioned elements later in the source order win over positioned elements earlier in the source order.

+ +

Can you change the stacking order? Yes, you can, by using the {{cssxref("z-index")}} property. "z-index" is a reference to the z-axis. You may recall from previous points in the source where we discussed web pages using horizontal (x-axis) and vertical (y-axis) coordinates to work out positioning for things like background images and drop shadow offsets. (0,0) is at the top left of the page (or element), and the x- and y-axes run across to the right and down the page (for left to right languages, anyway.)

+ +

Web pages also have a z-axis — an imaginary line that runs from the surface of your screen, towards your face (or whatever else you like to have in front of the screen). {{cssxref("z-index")}} values affect where positioned elements sit on that axis — positive values move them higher up the stack, and negative values move them lower down the stack. By default, positioned elements all have a z-index of auto, which is effectively 0.

+ +

To change the stacking order, try adding the following declaration to your p:nth-of-type(1) rule:

+ +
z-index: 1;
+ +

You should now see the finished example:

+ + + +

{{ EmbedLiveSample('Introducing_z-index', '100%', 400) }}

+ +

Note that z-index only accepts unitless index values; you can't specify that you want one element to be 23 pixels up the Z-axis — it doesn't work like that. Higher values will go above lower values, and it is up to you what values you use. Using 2 and 3 would give the same effect as 300 and 40000.

+ +
+

Note: You can see the example at this point live at 5_z-index.html (see source code).

+
+ +

Fixed positioning

+ +

There is one more type of positioning to cover — fixed. This works in exactly the same way as absolute positioning, with one key difference — whereas absolute positioning fixes an element in place relative to the {{htmlelement("html")}} element or its nearest positioned ancestor, fixed positioning fixes an element in place relative to the browser viewport itself. This means that you can create useful UI items that are fixed in place, like persisting navigation menus.

+ +

Let's put together a simple example to show what we mean. First of all, delete the existing p:nth-of-type(1) and .positioned rules from your CSS.

+ +

Now, update the body rule to remove the position: relative; declaration and add a fixed height, like so:

+ +
body {
+  width: 500px;
+  height: 1400px;
+  margin: 0 auto;
+}
+ +

Now we're going to give the {{htmlelement("h1")}} element position: fixed;, and get it to sit at the top center of the viewport. Add the following rule to your CSS:

+ +
h1 {
+  position: fixed;
+  top: 0;
+  width: 500px;
+  margin: 0 auto;
+  background: white;
+  padding: 10px;
+}
+ +

The top: 0; is required to make it stick to the top of the screen; we then give the heading the same width as the content column and use the faithful old margin: 0 auto; trick to center it. We then give it a white background and some padding, so the content won't be visible underneath it.

+ +

If you save and refresh now, you'll see a fun little effect whereby the heading stays fixed, and the content appears to scroll up and disappear underneath it. But we could improve this more — at the moment some of the content starts off underneath the heading. This is because the positioned heading no longer appears in the document flow, so the rest of the content moves up to the top. We need to move it all down a bit; we can do this by setting some top margin on the first paragraph. Add this now:

+ +
p:nth-of-type(1) {
+  margin-top: 60px;
+}
+ +

You should now see the finished example:

+ + + +

{{ EmbedLiveSample('Fixed_positioning', '100%', 400) }}

+ +
+

Note: You can see the example at this point live at 6_fixed-positioning.html (see source code).

+
+ +

Experimental: position sticky

+ +

There is a new positioning value available called position: sticky, support for which is not very widespread yet. This is basically a hybrid between relative and fixed position, which allows a positioned element to act like it is relatively positioned until it is scrolled to a certain threshold point (e.g. 10px from the top of the viewport), after which it becomes fixed.  See our position: sticky reference entry for more details and an example.

+ +

Summary

+ +

I'm sure you had fun playing with basic positioning — it is one of the essential tools behind creating complex CSS layouts and UI features. With that in mind, in the next article we'll have even more fun with positioning — there we'll go a step further and start to build up some real world useful things with it.

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}

+ +

 

+ +

In this module

+ + + +

 

diff --git a/files/es/learn/css/css_layout/soporte_a_navegadores_antiguos/index.html b/files/es/learn/css/css_layout/soporte_a_navegadores_antiguos/index.html new file mode 100644 index 0000000000..18065a1da5 --- /dev/null +++ b/files/es/learn/css/css_layout/soporte_a_navegadores_antiguos/index.html @@ -0,0 +1,237 @@ +--- +title: Soporte a navegadores antiguos +slug: Learn/CSS/CSS_layout/Soporte_a_navegadores_antiguos +translation_of: Learn/CSS/CSS_layout/Supporting_Older_Browsers +--- +
{{LearnSidebar}}
+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Legacy_Layout_methods", "Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension", "Learn/CSS/CSS_layout")}}

+ +

En este módulo recomendamos utilizar Flexbox y Grid como las herramientas principales para tus diseños. Sin embargo, habrá visitantes a tu sitio web que usen navegadores antiguos o navegadores que no admiten los métodos que has utilizado. Este siempre será el caso en la red: a medida que se desarrollan funciones nuevas, los diferentes navegadores priorizan cosas diferentes. Este artículo explica cómo usar técnicas web modernas sin perjudicar a los usuarios con tecnologías más antiguas.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (véase Introducción al HTML) y nociones de cómo funciona el CSS (véase Introducción al CSS).
Objetivo:Comprender cómo proporcionar compatibilidad para tus diseños en navegadores antiguos que podrían no admitir las funciones que deseas utilizar.
+ +

¿Cuál es la vista del navegador para tu sitio?

+ +

Cada sitio web es diferente en términos de público objetivo. Antes de decidir el enfoque a seguir, averigua la cantidad de visitantes que visitan tu sitio que utilizan navegadores antiguos. Esto es sencillo si se trata de un sitio web que simplemente modificas o reemplazas, porque probablemente haya análisis disponibles que te indiquen la tecnología que la gente utiliza. Si el sitio no tiene funciones de análisis o se trata de un sitio nuevo, hay sitios como Statcounter que pueden proporcionar estadísticas filtradas por ubicación.

+ +

También debes considerar el tipo de dispositivos y la forma en que las personas usan tu sitio; por ejemplo, puedes esperar un número de dispositivos móviles superior al promedio. La accesibilidad y las personas que utilizan tecnología de asistencia siempre deben tenerse en cuenta, pero para algunos sitios pueden ser aspectos aún más críticos. Según experiencia propia, los desarrolladores a menudo se preocupan demasiado por la experiencia de usuario de un 1% de usuarios que usan una versión antigua de Internet Explorer, y no consideran en absoluto el número mucho mayor de usuarios que tiene necesidades de accesibilidad especiales.

+ +

¿Qué compatibilidad presentan las funciones que vas a usar?

+ +

Una vez conozcas qué tipo de navegadores utiliza la gente que accede a tu sitio, puedes evaluar cualquier tecnología que desees utilizar según su compatibilidad y con qué facilidad es posible proporcionar una alternativa a los visitantes que no disponen de esa tecnología. Tratamos de facilitarte esta experiencia proporcionando información de compatibilidad de los navegadores en cada una de las páginas que detallan una propiedad CSS. Por ejemplo, echa un vistazo a la página de {{cssxref ("grid-template-columns")}}. En la parte inferior de esta página hay una tabla que enumera los navegadores principales, junto con la versión en la que comenzaron a admitir esta propiedad.

+ +

+ +

Otra forma popular de averiguar la compatibilidad de una característica es el sitio web Can I Use. Este sitio enumera la mayoría de las características de la Plataforma Web con información sobre el estado de compatibilidad de tu navegador. Puedes ver las estadísticas de uso por ubicación, cosa que resulta útil si trabajas en un sitio cuyos usuarios son de un territorio particular. Incluso puedes vincular tu cuenta de Google Analytics para obtener un análisis basado en tus datos de usuario.

+ +

Conocer las tecnologías de tus usuarios y las compatibilidades de las funciones que tal vez quieras usar te proporcionan una buena base para tomar todas tus decisiones y saber cuál es la mejor manera de dar compatibilidad a todos tus usuarios.

+ +

Compatibilidad no significa «verse igual»

+ +

Es posible que un sitio web no tenga el mismo aspecto en todos los navegadores, porque algunos de tus usuarios lo verán en un teléfono y otros en el ordenador. Del mismo modo, algunos de tus usuarios tendrán una versión antigua del navegador y otros el navegador más reciente. Es posible que algunos de tus usuarios estén escuchando el contenido leído por un lector de pantalla, o hayan ampliado la página para poderla leer. Dar compatibilidad a todos significa servir una versión de tus contenidos diseñada estratégicamente para que se vea genial con los navegadores modernos, pero aún sea utilizable en un nivel básico para los usuarios con navegadores más antiguos.

+ +

Un nivel básico de compatibilidad proviene de estructurar bien tus contenidos para que el flujo normal de tu página tenga sentido. Un usuario con un teléfono con funciones muy limitadas puede que no obtenga buena parte de tu CSS, pero el contenido fluirá de una manera que la lectura resulte fácil. Por lo tanto, un documento HTML bien estructurado siempre debe ser tu punto de partida. ¿Tu contenido tiene sentido si eliminas tu hoja de estilo?

+ +

Una opción es dejar esta vista simple del sitio como alternativa para las personas que utilizan navegadores muy antiguos o limitados. Si la cantidad de personas que visitan el sitio con estos navegadores es pequeña, quizá no tenga sentido comercial dedicar tiempo a tratar de proporcionarles una experiencia similar a la de las personas que utilizan navegadores modernos. Sería mejor dedicar el tiempo a cosas que proporcionen accesibilidad al sitio, y servir así a muchos más usuarios. Hay un punto medio entre una página HTML simple y todos esos recursos, y CSS realmente ha logrado que proporcionar estas soluciones alternativas resulte bastante sencillo.

+ +

Crear soluciones alternativas en CSS

+ +

Las especificaciones CSS contienen información que explica qué hace el navegador cuando se aplican dos métodos de diseño al mismo elemento. Esto significa que hay una definición de lo que sucede si un elemento flotante, por ejemplo, también es un elemento Grid que usa diseño de cuadrícula CSS. Combina esta información con el conocimiento de que los navegadores ignoran el CSS que no entienden, y tienes una manera de crear diseños simples utilizando las técnicas heredadas que ya hemos expuesto, que luego se sobrescriben con tu diseño de cuadrícula en los navegadores modernos que lo entienden.

+ +

En el ejemplo siguiente hemos especificado tres elementos de flotación <div> para que se muestren en una fila. Cualquier navegador que no sea compatible con el método de compaginación CSS Grid verá la hilera de cajas como un diseño con el método de flotación. Un elemento de flotación que se convierte en un elemento de cuadrícula pierde el comportamiento de flotación, lo que significa que al convertir el contenedor en un contenedor de cuadrícula, los elementos de flotación se convierten en elementos de cuadrícula. Si el navegador admite el diseño de cuadrícula, muestra la vista de cuadrícula; si no, ignora las propiedades relacionadas con el diseño de cuadrícula y utiliza el diseño de flotación.

+ +
+
* {box-sizing: border-box;}
+
+.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  max-width: 400px;
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+
+.item {
+  float: left;
+  border-radius: 5px;
+  background-color: rgb(207,232,220);
+  padding: 1em;
+}
+
+ +
<div class="wrapper">
+  <div class="item">Artículo uno</div>
+  <div class="item">Artículo dos</div>
+  <div class="item">Artículo tres</div>
+</div>
+
+ +

{{ EmbedLiveSample('Example1', '100%', '200') }}

+
+ +
+

Nota: La propiedad {{cssxref ("clear")}} tampoco tiene efecto una vez que el elemento al que se le aplica se convierte en un elemento de cuadrícula, por lo que podrías tener una compaginación con un pie clear, que luego pase a ser un elemento de compaginación en cuadrícula.

+
+ +

Métodos de soluciones alternativas

+ +

Numerosos métodos de compaginación se pueden usar de manera similar a este ejemplo con comportamiento de flotación. Puedes elegir el que tenga más sentido para el patrón de compaginación que necesitas crear.

+ +
+
float y clear
+
Como se muestra arriba, las propiedades float o clear dejan de afectar a la compaginación si los elementos afectados por estas propiedades pasan a ser de tipo flexible o de cuadrícula.
+
display: inline-block;
+
Este método se puede utilizar para crear compaginaciones en columnas; si un elemento tiene establecido un comportamiento display: inline-block pero se convierte a elemento con compaginación de tipo flexible o de cuadrícula, el comportamiento inline-block se ignora.
+
display: table;
+
El método de creación de tablas CSS que se describe en la introducción de estos artículos puede utilizarse como opción alternativa. Los elementos que tienen diseños de tabla CSS pierden este comportamiento si se convierten en elementos con comportamiento flexible o de cuadrícula. Es importante destacar que no se crearán las cajas sin nombre que fueron creadas para arreglar la estructura de tabla.
+
Compaginación en columnas
+
Para ciertos tipos de compaginación puedes usar multi-col como opción alternativa; si tu contenedor tiene alguna propiedad column-* definida y se convierte en un contenedor con comportamiento de cuadrícula, se anula el comportamiento en columnas.
+
Flexbox como opción alternativa a la cuadrícula
+
Flexbox tiene una compatibilidad mayor con los navegadores que Grid porque es compatible con Internet Explorer 10 y 11, aunque te recomendamos que consultes la información que encontrarás más adelante en este artículo sobre la compatibilidad bastante irregular y confusa de Flexbox en navegadores más antiguos. Si conviertes un contenedor flexible en un contenedor de cuadrícula, se ignorará cualquier propiedad flex aplicada a los elementos secundarios.
+
+ +

Observa que si usas el CSS de esta manera puedes proporcionar una experiencia de usuario decente para ajustar muchas compaginaciones en navegadores antiguos. Añadimos una compaginación más simple basada en técnicas antiguas y con buena compatibilidad, y luego usamos el CSS más nuevo para crear la compaginación que va a ver más del 90% de tu público. Sin embargo, hay casos en los que el código alternativo va a tener que incluir algo que también van a interpretar los navegadores nuevos. Un buen ejemplo de esto es si queremos añadir anchos en porcentaje a nuestros elementos de flotación para que el aspecto de las columnas reproduzca mejor la visualización en cuadrícula, expandiendo para llenar el contenedor.

+ +

En la compaginación de flotación, el porcentaje se calcula con respecto al contenedor: 33,333% es un tercio del ancho del contenedor. Sin embargo, en el método Grid ese 33,333% se calcula con respecto al área de la cuadrícula en la que el elemento está ubicado, por lo que en realidad se convierte en un tercio del tamaño que queremos una vez que se introduce la compaginación en cuadrícula.

+ +
+
* {box-sizing: border-box;}
+
+.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  max-width: 400px;
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+
+.item {
+  float: left;
+  border-radius: 5px;
+  background-color: rgb(207,232,220);
+  padding: 1em;
+  width: 33.333%;
+}
+
+ +
<div class="wrapper">
+  <div class="item">Artículo uno</div>
+  <div class="item">Artículo dos</div>
+  <div class="item">Artículo tres</div>
+</div>
+
+ +

{{ EmbedLiveSample('Example2', '100%', '200') }}

+
+ +

Para tratar este problema, necesitamos tener un modo de detectar si Grid es compatible y, por lo tanto, si anulará el ancho. El CSS tiene una solución.

+ +

Consultar las propiedades

+ +

Consultar las propiedades te permite comprobar si un navegador admite alguna característica CSS en particular. Esto significa que puedes escribir algunos CSS para navegadores que no admitan una propiedad determinada y luego verificar si el navegador es compatible, y añadir tu elegante diseño de ser así.

+ +

Si añadimos al ejemplo anterior una consulta de las propiedades, podemos usarla para volver a establecer a auto los anchos de nuestros elementos, si sabemos que hay compatibilidad para la compaginación en cuadrícula.

+ +
+
* {box-sizing: border-box;}
+
+.wrapper {
+  background-color: rgb(79,185,227);
+  padding: 10px;
+  max-width: 400px;
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+
+.item {
+  float: left;
+  border-radius: 5px;
+  background-color: rgb(207,232,220);
+  padding: 1em;
+  width: 33.333%;
+}
+
+@supports (display: grid) {
+  .item {
+      width: auto;
+  }
+}
+
+ +
<div class="wrapper">
+  <div class="item">Elemento uno</div>
+  <div class="item">Elemento dos</div>
+  <div class="item">Elemento tres</div>
+</div>
+
+ +

{{ EmbedLiveSample('Example3', '100%', '200') }}

+
+ +

La compatibilidad para la consulta de propiedades es muy buena en todos los navegadores modernos, pero debes tener en cuenta que son los navegadores que no admiten CSS Grid los que tampoco admiten la consulta de propiedades. Esto significa que para esos navegadores funcionará un enfoque como el que acabamos de detallar. Lo que hacemos es escribir primero nuestro CSS anterior sin hacer ninguna consulta de propiedades. Los navegadores que no admiten Grid y que no admiten la consulta de propiedades utilizan esa información de diseño que pueden entender e ignoran por completo todo lo demás. Los navegadores que admiten la consulta de propiedades también admiten CSS Grid y, por lo tanto, ejecutan el código de cuadrícula y el código de la consulta de propiedades.

+ +

La especificación para la consulta de propiedades también incluye la posibilidad de probar si un navegador no admite una propiedad; esto solo es útil si el navegador admite consultas de propiedades. En el futuro bastará con el enfoque de verificar la falta de compatibilidad, porque los navegadores que no tienen compatibilidad para la consulta de propiedades desaparecen. Por ahora, sin embargo, utiliza el enfoque de usar el CSS anterior y luego sobrescribirlo para obtener la mejor compatibilidad.

+ +

Versiones anteriores de Flexbox

+ +

En versiones anteriores de navegadores, puedes encontrar versiones anteriores de la especificación Flexbox. En el momento de escribir esto se trata principalmente de un problema con Internet Explorer 10, que usa el prefijo -ms- para Flexbox. Esto también significa que algunos artículos y tutoriales están obsoletos; esta guía útil te ayuda a verificarlo y también puede ayudarte si necesitas compatibilidad Flexbox en navegadores muy antiguos.

+ +

La versión prefijada de Grid de Internet Explorer 10 y 11

+ +

La especificación CSS Grid se prototipó inicialmente en Internet Explorer 10; esto significa que si bien IE10 e IE11 no tienen compatibilidad de cuadrícula moderna, sí tienen una versión de compaginación en cuadrícula, que es muy útil, aunque diferente de la especificación moderna que documentamos en este sitio. Las implementaciones de IE10 y 11 tienen el prefijo -ms-, lo que significa que puedes usarlo para estos navegadores y los navegadores que no sean de Microsoft lo ignorarán. Sin embargo, Edge todavía comprende la sintaxis anterior, así que ten cuidado de que todo se sobrescriba de forma segura en tu cuadrícula de CSS moderna.

+ +

La guía de Mejora progresiva en la compaginación en cuadrícula puede ayudarte a comprender la versión de la cuadrícula de Internet Explorer, y hemos incluido algunos enlaces útiles adicionales al final de este artículo. Sin embargo, a menos que tengas una gran cantidad de visitantes con versiones anteriores de Internet Explorer, puede que te resulte mejor centrarte en crear una reserva que funcione para todos los navegadores no compatibles.

+ +

Pruebas con navegadores antiguos

+ +

Dado que la mayoría de los navegadores ya son compatibles con Flexbox y Grid, puede resultar en efecto difícil hacer pruebas con navegadores más antiguos. Una forma es utilizar una herramienta de prueba en línea como Sauce Labs, como se detalla en el módulo de comprobación de compatibilidad entre navegadores.

+ +

También puedes descargar e instalar máquinas virtuales y ejecutar versiones anteriores de navegadores en un entorno de tu propio ordenador. Tener acceso a versiones anteriores de Internet Explorer es particularmente útil, y para ese propósito, Microsoft ha puesto a disposición de los usuarios una variedad de máquinas virtuales de descarga gratuita. Están disponibles para los sistemas operativos Mac, Windows y Linux, por lo que resultan una manera excelente de hacer pruebas con los navegadores Windows antiguos y modernos, incluso si no utilizas una computadora con sistema Windows.

+ +

Resumen

+ +

Ahora tienes el conocimiento para usar con confianza técnicas como Grid y Flexbox, crear soluciones alternativas para navegadores más antiguos y utilizar cualquier técnica nueva que pueda surgir en el futuro.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Legacy_Layout_methods", "Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension", "Learn/CSS/CSS_layout")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/first_steps/comenzando_css/index.html b/files/es/learn/css/first_steps/comenzando_css/index.html new file mode 100644 index 0000000000..1da9edb582 --- /dev/null +++ b/files/es/learn/css/first_steps/comenzando_css/index.html @@ -0,0 +1,264 @@ +--- +title: Empezar con CSS +slug: Learn/CSS/First_steps/Comenzando_CSS +tags: + - Aprender + - CSS + - Clases + - Ejemplo + - Elementos + - Estado + - Principiante + - Selectores + - Sintaxis +translation_of: Learn/CSS/First_steps/Getting_started +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}
+ +

En este artículo aplicaremos CSS a un documento HTML sencillo para aprender algunos elementos prácticos sobre este lenguaje.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajo con archivos y conceptos básicos de HTML (véase Introducción al HTML).
Objetivo:Comprender los conceptos básicos para vincular un documento CSS a un archivo HTML y dar a un texto un formato sencillo con CSS.
+ +

Empezamos con algo de HTML

+ +

Nuestro punto de partida es un documento HTML. Puedes copiar el código de abajo si quieres trabajar en tu ordenador. Guarda el siguiente código como index.html en una carpeta de tu equipo.

+ +
<!doctype html>
+<html lang="es">
+<head>
+    <meta charset="utf-8">
+    <title>Empezamos con el CSS</title>
+</head>
+
+<body>
+
+    <h1>Soy un título de nivel uno</h1>
+
+    <p>Este es un párrafo de texto. En el texto hay un <span>elemento span</span>
+y también un <a href="http://example.com">enlace</a>.</p>
+
+    <p>Este es el segundo párrafo. Contiene un elemento <em>destacado</em>.</p>
+
+    <ul>
+        <li>Punto uno</li>
+        <li>Punto dos</li>
+        <li>Punto <em>tres</em></li>
+    </ul>
+
+</body>
+
+</html>
+
+ +
+

Nota: Si lees esto en un dispositivo o un entorno donde no puedes crear archivos fácilmente, no te preocupes. A continuación hay editores de código en vivo que van a permitirte escribir ejemplos de código en esta misma página.

+
+ +

Agregar CSS a un documento

+ +

Lo primero que se debe hacer es decirle al documento HTML que hay algunas reglas CSS que queremos que use. Hay tres formas diferentes de aplicar CSS a un documento HTML, sin embargo, por ahora, veremos la forma más habitual y útil de hacerlo: vincular el CSS desde el encabezado del documento.

+ +

Crea un archivo en la misma carpeta que tu documento HTML y guárdalo como styles.css. La extensión .css muestra que es un archivo CSS.

+ +

Para vincular styles.css a index.html, añade la siguiente línea en algún lugar dentro del {{htmlelement ("head")}} del documento HTML:

+ +
<link rel="stylesheet" href="styles.css">
+ +

Este elemento {{htmlelement ("link")}} le dice al navegador que hay una hoja de estilo con el atributo rel y la ubicación de esa hoja de estilo como el valor del atributo href. Puedes probar si el CSS funciona añadiendo una regla a styles.css. Usando el editor de código, añade lo siguiente al archivo CSS:

+ +
h1 {
+  color: red;
+}
+ +

Guarda los archivos HTML y CSS antes de volver a cargar la página en un navegador web. Ahora el título de nivel uno de la parte superior del documento debería ser rojo. Si esto sucede, ¡felicidades!: has aplicado correctamente un poco de CSS a un documento HTML. Si no lo hace, verifica que hayas escrito todo correctamente.

+ +

Puedes continuar trabajando en styles.css localmente o usar nuestro editor interactivo para continuar con este tutorial. El editor interactivo actúa como si el CSS del primer panel estuviera vinculado al documento HTML, tal como lo hemos hecho con el documento anterior.

+ +

Dar formato a elementos HTML

+ +

Al poner nuestro título de encabezado en rojo, ya hemos demostrado que podemos elegir un elemento HTML y darle formato. Hacemos esto con un selector de elementos: un selector que coincide directamente con el nombre de un elemento HTML. Para determinar todos los párrafos del documento, se usa el selector p. Para hacer que todos los párrafos se vean verdes se usa:

+ +
p {
+  color: green;
+}
+ +

Puedes determinar múltiples selectores a la vez, separándolos con una coma. Si queremos que todos los párrafos y todos los elementos de la lista sean verdes, el código se verá así:

+ +
p, li {
+    color: green;
+}
+ +

Pruébalo en el editor interactivo que encontrarás a continuación (edita los cuadros de código) o en tu documento CSS.

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started1.html", '100%', 900)}} 

+ +

Cambiar el comportamiento predeterminado de los elementos

+ +

Cuando miramos un documento HTML bien marcado, incluso con algo tan simple como nuestro ejemplo, podemos ver que el navegador facilita la legibilidad de este documento HTML al añadir un estilo predeterminado. Los títulos se muestran grandes y en negrita, y la lista tiene viñetas. Esto sucede porque los navegadores tienen hojas de estilo internas que contienen estilos predeterminados, los cuales se aplican a todas las páginas por defecto. Sin ellos, todo el texto se uniría en un grupo y tendríamos que darle formato desde cero. Todos los navegadores modernos muestran el contenido HTML por defecto de la misma manera.

+ +

Sin embargo, a menudo querrás algo diferente a la elección que ha hecho el navegador. Esto se puede solucionar con el simple hecho de escoger el elemento HTML que deseas cambiar y utilizar una regla CSS para cambiar su apariencia.  Un buen ejemplo es <ul>, que muestra una lista desordenada. Tiene viñetas y, si decidimos que no las queremos, podemos eliminarlas de este modo:

+ +
li {
+  list-style-type: none;
+}
+ +

Ahora, intenta añadir esto a tu CSS.

+ +

Es muy conveniente consultar en MDN la propiedad list-style-type para ver qué valores admite. Echa un vistazo a la página de list-style-type y encontrarás un ejemplo interactivo en la parte superior para probar diferentes valores (todos los permitidos se detallan más abajo en esa misma página).

+ +

Al mirar esa página, descubrirás que, además de eliminar las viñetas de la lista, también puedes cambiarlas. Intenta cambiarlas por unas cuadradas utilizando el valor square.

+ +

Añadir una clase

+ +

Hasta ahora, hemos utilizado elementos cuyo nombre se basa en el nombre de elemento que reciben en HTML. Esto funciona siempre que se desee que todos los elementos de ese tipo tengan el mismo aspecto en el documento. La mayoría de las veces no es el caso, por lo que deberás encontrar una manera de seleccionar un subconjunto de los elementos sin que cambien los demás. La forma más común de hacer esto es añadir una clase al elemento HTML y determinarla.

+ +

En tu documento HTML, añade al segundo elemento de la lista un atributo de clase. Debería verse así:

+ +
<ul>
+  <li>Punto uno</li>
+  <li class = "special">Punto dos</li>
+  <li>Punto <em>tres</em></li>
+</ul>
+ +

En tu CSS, puedes seleccionar una clase special creando un selector que comience con un carácter de punto final. Añade lo siguiente a tu archivo CSS:

+ +
.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

Guarda y actualiza para ver cuál es el resultado.

+ +

Puedes aplicar la clase special a cualquier elemento de la página que desees que tenga el mismo aspecto que este elemento de lista. Por ejemplo, es posible que desees que el <span> del párrafo también sea naranja y en negrita. Intenta añadirle una class special, luego vuelve a cargar la página y observa qué sucede.

+ +

A veces verás reglas con un selector que enumera el selector de elementos HTML junto con la clase:

+ +
li.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

Esta sintaxis significa «determina cualquier elemento li que tenga una clase special». Si hicieras esto, ya no podrías aplicar la clase a un elemento <span> u otro elemento simplemente añadiéndole la clase; tendrías que añadir ese elemento a la lista de selectores:

+ +
li.special,
+span.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

Como puedes imaginar, algunas clases pueden aplicarse a muchos elementos y no queremos tener que seguir editando el CSS cada vez que algo nuevo necesita adoptar ese estilo. Por lo tanto, a veces es mejor eludir el elemento y simplemente referirse a la clase, a menos que sepas que vas a querer crear algunas reglas especiales para un solo elemento y tal vez quieras asegurarte de que no se apliquen a otros elementos.

+ +

Dar formato según la ubicación en un documento

+ +

Hay momentos en los que querrás que algo se vea diferente en función de dónde esté en el documento. Hay múltiples selectores que pueden hacerlo, pero por ahora veremos solo un par. En nuestro documento hay dos elementos <em>: uno dentro de un párrafo y el otro dentro de un elemento de la lista. Para seleccionar solo un <em> que esté anidado dentro de un elemento <li>, podemos usar un selector llamado combinador descendente, que simplemente toma la forma de un espacio entre otros dos selectores.

+ +

Añade la siguiente regla a la hoja de estilo.

+ +
li em {
+  color: rebeccapurple;
+}
+ +

Este selector separará cualquier elemento <em> que esté dentro de (un descendiente de) <li>. Entonces, en tu documento de ejemplo, deberías encontrar que el <em> del tercer elemento de la lista es morado, pero el que hay en el párrafo no ha cambiado.

+ +

Otra cosa que puedes probar es dar formato un párrafo que venga directamente a continuación de un título que esté en el mismo nivel de jerarquía en el HTML. Para hacerlo, coloca un + (un combinador hermano adyacente) entre los selectores.

+ +

Intenta añadir también esta regla a la hoja de estilo:

+ +
h1 + p {
+  font-size: 200%;
+}
+ +

El ejemplo que encontrarás a continuación incluye las dos reglas anteriores. Intenta añadir una regla para que un span dentro de un párrafo se vuelva rojo. Sabrás si lo has hecho bien si el <span> en el primer párrafo se vuelve rojo pero el que hay en el primer elemento de la lista no cambia de color.

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started2.html", '100%', 1100)}}

+ +
+

Nota: Como puedes ver, el CSS nos ofrece varias formas de seleccionar elementos, y hasta ahora solo hemos arañado la superficie. Examinaremos todos estos selectores y muchos más en los artículos correspondientes a Selectores que encontrarás más adelante.

+
+ +

Dar formato según el estado

+ +

El último tipo de estilo que veremos en este tutorial es la capacidad de dar formato a los elementos en función de su estado. Un ejemplo sencillo es el estilo de los enlaces. Cuando damos formato a un enlace, necesitamos seleccionar el elemento <a> (anclaje). Tiene diferentes estados dependiendo de si se ha visitado o no, se pasa por encima, o se presiona con el teclado o se hace clic (se activa). Puedes usar CSS para dar formato a estos diferentes estados. El CSS que encontrarás a continuación presenta en color rosa los enlaces que no se han visitado y en verde los que sí.

+ +
a:link {
+  color: pink;
+}
+
+a:visited {
+  color: green;
+}
+ +

Puedes cambiar la apariencia del enlace, por ejemplo, eliminando el subrayado, lo que se logra mediante la siguiente regla:

+ +
a:hover {
+  text-decoration: none;
+}
+ +

En el ejemplo que encontrarás a continuación, puedes jugar con diferentes valores para los distintos estados de un enlace. Hemos añadido las reglas anteriores y ahora nos damos cuenta de que el color rosa es demasiado claro y difícil de leer, ¿por qué no cambiarlo a otro que se vea mejor? ¿Puedes poner los enlaces en negrita?

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started3.html", '100%', 900)}} 

+ +

Hemos eliminado el subrayado del enlace cuando el ratón se pasa por encima, y se puede eliminar de todos los estados de un enlace. Sin embargo, vale la pena recordar que en una página web real deberás asegurarte de que los visitantes sepan reconocer que se trata de un enlace. Que aparezca subrayado puede ser una pista importante para que las personas se den cuenta de que pueden hacer clic en una palabra dentro del párrafo, ya que es a lo que están acostumbrados. Al igual que con todo en CSS, existe la posibilidad de que tus cambios resten accesibilidad al documento. Intentaremos resaltar estas posibles dificultades en los lugares apropiados.

+ +
+

Nota: a menudo verás que se menciona la accesibilidad en estas lecciones y en MDN. Cuando hablamos de accesibilidad nos referimos al requisito de que nuestras páginas web sean comprensibles y usables para todas las personas.

+ +

Puede que tu visitante acceda a la página desde un ordenador con ratón o trackpad, o un teléfono inteligente con pantalla táctil. O puede que use un lector de pantalla que lea el contenido del documento, así como puede que necesite un tamaño de texto más grande o navegar por la página usando solo el teclado.

+ +

Un documento HTML simple es, generalmente, accesible para todos. Es importante que el documento no pierda accesibilidad a medida que vayas aplicándole estilo.

+
+ +

Combinaciones de selectores y combinadores

+ +

Vale la pena señalar que puedes hacer múltiples combinaciones de selectores y combinadores. Por ejemplo:

+ +
/* selecciona cualquier elemento <span> que se encuentre dentro de un <p>, que esté dentro de un <artículo> */
+artículo p span { ... }
+
+/* selecciona cualquier <p> que se encuentre directamente después de <ul>, que va directamente después de <h1> */
+h1 + ul + p { ... }
+ +

También puedes combinar varios tipos juntos. Intenta añadir lo siguiente al código:

+ +
body h1 + p .special {
+  color: yellow;
+  background-color: black;
+  padding: 5px;
+}
+ +

Dará formato a cualquier elemento con la clase special, dentro de un elemento <p> que venga justo después de <h1>, el cual se encuentra dentro de <body>. ¡Uf!

+ +

En el HTML original que proporcionamos, el único elemento al que esto aplica estilo es <span class="special">.

+ +

No te preocupes si ahora mismo te parece complicado: irás acostumbrarte a medida que escribas más CSS.

+ +

Para terminar

+ +

En este tutorial, hemos visto varias formas con las que se puede diseñar un documento usando CSS. Desarrollaremos este conocimiento a medida que avancemos con el resto de las lecciones. Sin embargo, ahora ya sabes lo suficiente como para aplicar estilo al texto, aplicar CSS en función de diferentes formas de determinar elementos en el documento y buscar propiedades y valores en la documentación de MDN.

+ +

En el próximo artículo, veremos cómo se estructura el CSS.

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}

+ +

En este módulo

+ +
    +
  1. ¿Qué es el CSS?
  2. +
  3. Empezar con CSS
  4. +
  5. Cómo se estructura el CSS
  6. +
  7. Cómo funciona el CSS
  8. +
  9. Pon en práctica tus conocimientos nuevos
  10. +
diff --git a/files/es/learn/css/first_steps/como_funciona_css/index.html b/files/es/learn/css/first_steps/como_funciona_css/index.html new file mode 100644 index 0000000000..920212e080 --- /dev/null +++ b/files/es/learn/css/first_steps/como_funciona_css/index.html @@ -0,0 +1,156 @@ +--- +title: Cómo funciona CSS +slug: Learn/CSS/First_steps/Como_funciona_CSS +translation_of: Learn/CSS/First_steps/How_CSS_works +--- +

{{LearnSidebar}}
+ {{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

+ +

Hemos aprendido los conceptos básicos de CSS, para qué sirve y cómo escribir hojas de estilo simples. En esta lección vamos a echar un vistazo a cómo un navegador crea una página web a partir de CSS y HTML.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de cómo trabajar con archivos y conceptos básicos de HTML (véase Introducción a HTML).
Objetivo:Entender los conceptos básicos de cómo el navegador analiza el CSS y el HTML y lo que sucede cuando encuentra un CSS que no entiende.
+ +

¿Cómo funciona realmente el CSS?

+ +

Cuando un navegador muestra un documento, ha de combinar el contenido con la información de estilo del documento. Procesa el documento en una serie de etapas, que enumeraremos a continuación. Ten en cuenta que este es un modelo muy simplificado de lo que sucede cuando un navegador carga una página web y que cada navegador gestiona el proceso de manera diferente. Pero esto es más o menos lo que sucede.

+ +
    +
  1. El navegador carga el HTML (por ejemplo, lo recibe de la red).
  2. +
  3. Convierte el {{Glossary("HTML")}} en un {{Glossary("DOM")}} (Modelo de objetos del documento). El DOM representa el documento en la memoria del ordenador. Lo explicaremos más detalladamente en la sección siguiente.
  4. +
  5. Entonces, el navegador va a buscar la mayor parte de los recursos vinculados al documento HTML, como las imágenes y los videos incrustados... ¡y también el CSS vinculado! JavaScript aparece un poco más adelante en el proceso, pero no vamos a hablar de ello aún para evitar complicar las cosas.
  6. +
  7. El navegador analiza el CSS y ordena en diferentes «cubos» las diferentes reglas según el tipo de selector. Por ejemplo, elemento, clase, ID, y así sucesivamente. Para cada tipo de selector que encuentres, calcula qué reglas deben aplicarse y a qué nodos en el DOM se les aplica el estilo según corresponda (este paso intermedio se llama árbol de renderización).
  8. +
  9. El árbol de renderización presenta la estructura en que los nodos deben aparecer después de aplicarle las reglas.
  10. +
  11. En la pantalla se muestra el aspecto visual de la página (esta etapa se llama pintura).
  12. +
+ +

El siguiente diagrama ofrece una visión sencilla de este proceso.

+ +

+ +

Acerca del DOM

+ +

Un DOM tiene una estructura en forma de árbol. Cada elemento, atributo o bloque en el lenguaje de marcado se convierte en un {{Glossary("Node/DOM","nodo DOM")}} con estructura de árbol. Los nodos se definen por su relación con otros nodos DOM. Algunos elementos son padres de nodos secundarios, y estos nodos hijos tienen hermanos.

+ +

Comprender el DOM te ayuda a diseñar, depurar y mantener tu CSS porque en el DOM es donde tu CSS se encuentra con el contenido del documento. Cuando comiences a trabajar con las herramientas DevTools (o herramientas del desarrollador) del navegador, te moverás por el DOM mientras seleccionas elementos con el fin de ver qué reglas se aplican.

+ +

Una representación real de un DOM

+ +

En lugar de una explicación larga y aburrida, veamos un ejemplo para entender cómo un código HTML se convierte en DOM.

+ +

Tomemos el siguiente código HTML:

+ +
<p>
+  Usaremos:
+  <span>Hojas</span>
+  <span>de estilo</span>
+  <span>en cascada</span>
+</p>
+
+ +

En el DOM, el nodo que se corresponde con nuestro elemento <p> es un padre. Sus hijos son un nodo de texto y los tres nodos correspondientes a nuestros elementos <span>. Los nodos SPAN son también los padres, y los nodos de texto sus hijos:

+ +
P
+├─ "Usaremos:"
+├─ SPAN
+|  └─ "Hojas"
+├─ SPAN
+|  └─ "de estilo"
+└─ SPAN
+   └─ "en cascada"
+
+ +

Así es como un navegador interpreta el código HTML anterior, interpreta el árbol DOM y luego lo muestra en el navegador, así:

+ +

{{EmbedLiveSample('Una_representación_real_de_un_DOM', '100%', 55)}}

+ + + +

La aplicación de CSS al DOM

+ +

Pongamos que hemos añadido un poco de CSS a nuestro documento, para darle estilo. Una vez más, el HTML es el siguiente:

+ +
<p>
+  Usaremos:
+  <span>Hojas</span>
+  <span>de estilo</span>
+  <span>en cascada</span>
+</p>
+ +

Supongamos que le aplicamos el CSS siguiente:

+ +
span {
+  border: 1px solid black;
+  background-color: lime;
+}
+ +

El navegador analizará el código HTML y creará un DOM a partir de este. A continuación, analizará el CSS. Dado que la única regla disponible en el CSS tiene un selector span, el navegador ¡ordenará el CSS muy rápidamente! Aplicará la regla a cada uno de los tres <span>, que mostrarán en pantalla la representación visual final.

+ +

La salida actualizada es la siguiente:

+ +

{{EmbedLiveSample ( 'La_aplicación_de_CSS_al_DOM', '100%', 55)}}

+ +

En nuestro artículo Depurar el CSS que encontrarás en el siguiente módulo, vamos a utilizar las herramientas DevTools del navegador para depurar posibles problemas en el CSS. También aprenderemos más sobre cómo el navegador interpreta el CSS.

+ +

¿Qué ocurre si un navegador encuentra CSS que no entiende?

+ +

En una lección anterior mencionamos que no todos los navegadores implementan las novedades de CSS en el mismo momento. Además, no todo el mundo utiliza la última versión de un navegador. Dado que el CSS está en desarrollo constante y, por lo tanto, por delante de lo que los navegadores pueden reconocer, puede que te preguntes qué sucede si un navegador encuentra un selector o una declaración CSS que no reconoce.

+ +

La respuesta es que no hace nada y simplemente pasa a la siguiente parte del CSS.

+ +

Si un navegador analiza tus reglas y encuentra una propiedad o un valor que no entiende, lo ignora y avanza hasta la declaración siguiente. Esto sucederá si has cometido un error y has escrito mal una propiedad o un valor, o si la propiedad o el valor son demasiado nuevos y el navegador aún no los admite.

+ +

Del mismo modo, si un navegador encuentra un selector que no entiende, lo ignorará y pasará al siguiente.

+ +

En el siguiente ejemplo hemos utilizado la ortografía británica para la propiedad color, que invalida la propiedad porque no la reconoce. Así que el párrafo no se muestra en azul. Sin embargo, se han aplicado todos los demás estilos del CSS; solo se ha ignorado la línea que no es válida.

+ +
+
<p>Quiero este texto en grande, en negrita y en color azul.</p>
+ +
p {
+  font-weight: bold;
+  colour: blue; /* Ortografía incorrecta de la propiedad color */
+  font-size: 200%;
+}
+
+ +

{{EmbedLiveSample('Skipping_example', '100%', 200)}}

+ +

Este comportamiento es muy útil. Significa que puedes utilizar el CSS nuevo como una mejora, a sabiendas de que no se producirá ningún error si no se entiende: o bien el navegador entiende la característica nueva o no lo hace. Combinado con el funcionamiento del modo en cascada con el hecho de que los navegadores utilizarán la última CSS que encuentren en la hoja de estilo, cuando haya dos reglas con el mismo nivel de especificidad, también puedes ofrecer alternativas para los navegadores que no admiten el CSS nuevo.

+ +

Esto funciona especialmente bien cuando quieres utilizar un valor que es bastante nuevo que no admiten todos los navegadores. Por ejemplo, algunos navegadores antiguos no entienden calc() como valor. Podríamos dar un valor de sustitución para el ancho de una caja en píxeles, y a continuación dar un ancho con un valor calc() de 100% - 50px. Los navegadores antiguos usarán la versión en píxeles y harán caso omiso de la indicación calc(), porque no la entienden. Los navegadores nuevos interpretarán la línea del ancho en píxeles, pero la anularán al llegar a la línea de calc() porque aparece después en la cascada.

+ +
.box {
+  width: 500px;
+  width: calc(100% - 50px);
+}
+ +

En lecciones posteriores veremos muchas más formas de cómo admitir navegadores diferentes.

+ +

Y finalmente

+ +

Casi has terminado este módulo; solo nos queda una cosa más por hacer. En el próximo artículo, pondrás en práctica tu conocimiento nuevo para cambiar el estilo de un ejemplo y probarte con un poco de CSS en el proceso.

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

+ +

En este módulo

+ +
    +
  1. ¿Qué es CSS?
  2. +
  3. Empezar con CSS
  4. +
  5. Cómo se estructura el CSS
  6. +
  7. Cómo funciona el CSS
  8. +
  9. Pon en práctica tus conocimientos nuevos
  10. +
diff --git a/files/es/learn/css/first_steps/como_se_estructura_css/index.html b/files/es/learn/css/first_steps/como_se_estructura_css/index.html new file mode 100644 index 0000000000..a3e9bb94b8 --- /dev/null +++ b/files/es/learn/css/first_steps/como_se_estructura_css/index.html @@ -0,0 +1,512 @@ +--- +title: Cómo se estructura el CSS +slug: Learn/CSS/First_steps/Como_se_estructura_CSS +translation_of: Learn/CSS/First_steps/How_CSS_is_structured +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}
+ +

Ahora que ya sabes qué es el CSS y conoces sus conceptos básicos, es hora de profundizar un poco más en la estructura del lenguaje en sí. Ya hemos visto muchos de los conceptos que aparecen en este artículo; puedes volver para recapitular si más adelante encuentras conceptos confusos.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de trabajo con archivos, conceptos básicos de HTML (véase Introducción al HTML) y una idea de cómo funciona el CSS.
Objetivo:Aprender en detalle las estructuras de sintaxis fundamentales de CSS.
+ +

Aplicar CSS al HTML

+ +

Lo primero que veremos son los tres métodos para aplicar CSS a un documento.

+ +

Hoja de estilo externa

+ +

En Empezar con el CSS, vinculamos una hoja de estilo externa a nuestra página. Este es el método más común y útil para adjuntar CSS a un documento, porque puedes vincular el CSS a varias páginas y dar estilo a todas ellas con la misma hoja de estilo. En la mayoría de los casos, las diferentes páginas de un sitio web se verán más o menos iguales, de modo que puedes usar el mismo conjunto de reglas para el aspecto y la interacción básicos.

+ +

Una hoja de estilo externa significa que el CSS está escrito en un archivo independiente con una extensión .css y que lo vinculas desde un elemento <link> de HTML:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi experimento CSS</title>
+    <link rel="stylesheet" href="styles.css">
+  </head>
+  <body>
+    <h1>¡Hola, mundo!</h1>
+    <p>Este es mi primer ejemplo de CSS</p>
+  </body>
+</html>
+ +

El archivo CSS podría parecerse a esto:

+ +
h1 {
+  color: blue;
+  background-color: yellow;
+  border: 1px solid black;
+}
+
+p {
+  color: red;
+}
+ +

El atributo href del elemento {{htmlelement("link")}} tiene que hacer referencia a un archivo de tu sistema de archivos.

+ +

En el ejemplo anterior, el archivo CSS está en la misma carpeta que el documento HTML, pero puedes colocarlo en otro lugar y especificar la ruta adecuada. Por ejemplo:

+ +
<!-- Dentro de un subdirectorio llamado styles dentro del directorio de trabajo -->
+<link rel="stylesheet" href="styles/style.css">
+
+<!-- Dentro de un subdirectorio llamado general, que está en un subdirectorio llamado styles, dentro del directorio de trabajo -->
+<link rel="stylesheet" href="styles/general/style.css">
+
+<!-- Sube un nivel de directorio, y luego dentro de un subdirectorio llamado styles -->
+<link rel="stylesheet" href="../styles/style.css">
+ +

Hoja de estilo interna

+ +

Una hoja de estilo interna es cuando no hay ningún archivo CSS externo, sino que colocas tu CSS dentro de un elemento {{htmlelement("style")}} contenido dentro del elemento {{htmlelement("head")}} del HTML.

+ +

En este caso, el HTML se vería así:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi experimento CSS</title>
+    <style>
+      h1 {
+        color: blue;
+        background-color: yellow;
+        border: 1px solid black;
+      }
+
+      p {
+        color: red;
+      }
+    </style>
+  </head>
+  <body>
+    <h1>¡Hola, mundo!</h1>
+    <p>Este es mi primer ejemplo de CSS</p>
+  </body>
+</html>
+ +

Esto puede ser útil en algunas circunstancias (tal vez estés trabajando con un sistema de administración de contenido donde no sea posible modificar los archivos CSS directamente), pero no es tan eficiente como las hojas de estilo externas: en una página web, deberías repetir el CSS en cada página y actualizarlo en varios lugares en caso de que hubiera que hacer cambios.

+ +

Estilos en línea

+ +

Los estilos en línea son declaraciones CSS que afectan a un solo elemento, contenido dentro de un atributo de style:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi experimento CSS</title>
+  </head>
+  <body>
+    <h1 style="color: blue;background-color: yellow;border: 1px solid black;">¡Hola mundo!</h1>
+    <p style="color:red;">Este es mi primer ejemplo de CSS</p>
+  </body>
+</html>
+ +

¡No hagas esto a menos que realmente tengas que hacerlo! Es realmente malo a la hora de realizar el mantenimiento (puede que tengas que actualizar la misma información varias veces en un mismo documento), y además mezcla tu información CSS para la presentación con tu información HTML para la estructura, lo que dificulta la lectura y la comprensión del código. Mantener los diferentes tipos de código separados facilita trabajar con ellos.

+ +

Hay ciertos lugares donde los estilos en línea son más comunes, o incluso aconsejables. Es posible que tengas que recurrir a ellos si realmente tu entorno de trabajo es restrictivo (tal vez el CMS solo te permita editar el cuerpo del HTML). También verás que se usan mucho en el correo electrónico en formato HTML para lograr la máxima compatibilidad con el mayor número de clientes.

+ +

Juguemos con el CSS de este artículo

+ +

En este artículo hay mucho CSS con el que jugar. Para hacerlo, recomendamos crear un nuevo directorio/carpeta en el ordenador, dentro de la cual deberás crear una copia de los siguientes dos archivos:

+ +

index.html:

+ +
<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Mis experimentos CSS</title>
+    <link rel="stylesheet" href="styles.css">
+  </head>
+  <body>
+
+    <p>Crea tu HTML de prueba aquí</p>
+
+  </body>
+</html>
+ +

styles.css:

+ +
/* Crea tu CSS de prueba aquí */
+
+p {
+  color: red;
+}
+ +

Entonces, cuando te encuentres con un CSS con el que desees experimentar, reemplaza el contenido <body> del HTML con algo de HTML sin estilos y añade CSS a tu archivo de CSS para darle estilo.

+ +

Si no estás en un sistema donde puedas crear archivos fácilmente, puedes utilizar el editor interactivo que encontrarás a continuación para experimentar.

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/experiment-sandbox.html", '100%', 800)}} 

+ +

¡Sigue leyendo y disfruta!

+ +

Selectores

+ +

No se puede hablar de CSS sin mencionar los selectores, de los cuales ya hemos descubierto varios tipos diferentes en la lección Empezar con el CSS. Un selector es, como determinamos, un elemento de nuestro documento HTML para aplicarle estilo. Si los estilos no se aplican correctamente, es probable que el selector no coincida con lo que crees que debería coincidir.

+ +

Cada regla CSS comienza con un selector o una lista de selectores que indican al navegador a qué elemento o elementos deben aplicarse dichas reglas. Todos los siguientes son ejemplos de selectores válidos o listas de selectores.

+ +
h1
+a:link
+.manythings
+#onething
+*
+.box p
+.box p:first-child
+h1, h2, .intro
+ +

Prueba a crear algunas reglas CSS que usen los selectores anteriores y algo de HTML sin estilos. Si no conoces alguna de las sintaxis anteriores, ¡prueba a buscarla en MDN!

+ +
+

Nota: Aprenderás mucho más sobre los selectores en nuestros tutoriales sobre selectores CSS de la próxima lección.

+
+ +

Especificidad

+ +

A menudo habrá situaciones en las que dos selectores podrían determinar un mismo elemento HTML. Considera la siguiente hoja de estilo, en que definimos una regla con un selector p que establecerá los párrafos en color azul, y también una clase que establecerá los elementos seleccionados en color rojo.

+ +
.special {
+  color: red;
+}
+
+p {
+  color: blue;
+}
+ +

Digamos que en nuestro documento HTML hay un párrafo con una clase special. Ambas reglas podrían aplicarse. ¿Cuál ganará? ¿De qué color crees que será nuestro párrafo?

+ +
<p class="special">¿De qué color soy?</p>
+ +

El lenguaje CSS tiene reglas para controlar cuál ganará en caso de colisión; reciben el nombre de cascada y especificidad. En el siguiente bloque de códigos hemos definido dos reglas para el selector p, pero el párrafo termina siendo de color azul. Esto se debe a que la declaración que lo establece en azul aparece más abajo en la hoja de estilo, y los estilos posteriores anulan a los anteriores. Así funciona la regla de la cascada.

+ +
p {
+  color: red;
+}
+
+p {
+  color: blue;
+}
+ +

Sin embargo, en el caso de nuestro primer bloque, que contiene un selector de clase y otro de elementos, la clase ganará. Esto hará que el párrafo sea rojo, incluso aunque aparezca antes en la hoja de estilo. Una clase se describe de forma más específica o con más especificidad que el selector de elementos, razón por la que gana.

+ +

Prueba el ejemplo anterior: añade el HTML a tu experimento, luego pon las dos reglas p { ... } a tu hoja de estilo. A continuación, cambia el primer selector p por .special para ver cómo cambia el estilo.

+ +

Las reglas de especificidad y de cascada pueden parecer un poco complicadas al principio. Son más fáciles de entender a medida que se van adquiriendo conocimientos de CSS. En nuestro artículo sobre Cascada y herencia, que abordaremos en la próxima lección, se explicará en detalle, incluyendo cómo calcular la especificidad. Por ahora, solo has de saber que existe y que a veces el CSS no se aplica como esperas porque algo más en la hoja de estilo tiene una mayor especificidad. El hecho de identificar que más de una regla podría aplicarse a un elemento es el primer paso para solucionar estos problemas.

+ +

Propiedades y valores

+ +

En su nivel más básico, el CSS consta de dos componentes básicos:

+ + + +

La siguiente imagen resalta una sola propiedad y valor. El nombre de la propiedad es color y el valor blue.

+ +

Una declaración resaltada en el CSS

+ +

Una propiedad emparejada con un valor se denomina declaración CSS. Las declaraciones CSS se colocan dentro de los bloques de declaración CSS. La siguiente imagen muestra nuestro CSS con el bloque de declaración resaltado.

+ +

Un bloque de declaración resaltado

+ +

Finalmente, los bloques de declaración CSS se combinan con selectores para producir conjuntos de reglas CSS (o reglas CSS). Nuestra imagen contiene dos reglas, una para el selector h1 y otra para el selector p. La regla para h1 está resaltada.

+ +

La regla para h1 resaltada

+ +

Establecer las propiedades de CSS según valores específicos es la función principal del lenguaje CSS. El motor CSS calcula qué declaraciones se aplican a cada elemento de una página para darle la compaginación y los estilos adecuados.

+ +
+

Importante: Las propiedades y valores de CSS son sensibles a mayúsculas y minúsculas. La propiedad y el valor de cada par están separados por dos puntos (:).

+
+ +

Prueba a buscar diferentes valores de las siguientes propiedades y escribe reglas CSS que se puedan aplicar a diferentes elementos HTML:

+ + + +
+

Importante: Si una propiedad es desconocida o si un valor no es válido para una propiedad determinada, la declaración se considera inválida y el motor CSS del navegador la ignora por completo.

+
+ +
+

Importante: En CSS (y otros estándares web) se ha acordado establecer como estándar la ortografía en inglés de los EE. UU. para solucionar las incertidumbres idiomáticas. Por ejemplo, siempre hay que escribir color. Si se escribe colour, no funcionará.

+
+ +

Las funciones

+ +

Si bien la mayoría de valores son palabras clave relativamente simples o valores numéricos, es posible que algunos valores tomen la forma de una función. Un ejemplo sería la función calc(). Esta función te permite hacer operaciones matemáticas sencillas desde tu CSS, por ejemplo:

+ +
+
<div class="external"> <div class="box">La caja interior es del 90% - 30px.</div></div>
+ +
.outer {
+  border: 5px solid black;
+}
+
+.box {
+  padding: 10px;
+  width: calc(90% - 30px);
+  background-color: rebeccapurple;
+  color: white;
+}
+
+ +

Esto se traduce así:

+ +

{{EmbedLiveSample('calc_example', '100%', 200)}}

+ +

Una función consta del nombre de la función y, a continuación, unos paréntesis entre los que se colocan los valores permitidos para esa función. En el caso del ejemplo calc() anterior, pedimos que el ancho de esta caja sea del 90% del ancho del bloque que la contiene, menos 30 píxeles. Esto no es algo que podamos calcular con anticipación y simplemente introducir el valor en el CSS, ya que no sabemos cuál será el 90%. Como con todos los valores, la página correspondiente del proyecto MDN tendrá ejemplos de uso para que puedas ver cómo funciona.

+ +

Otro ejemplo serían los diversos valores para {{cssxref ("transform")}}, como rotate().

+ +
+
<div class="box"></div>
+ +
.box {
+  margin: 30px;
+  width: 100px;
+  height: 100px;
+  background-color: rebeccapurple;
+  transform: rotate(0.8turn)
+}
+
+ +

El resultado del código anterior se ve así:

+ +

{{EmbedLiveSample('transform_example', '100%', 200)}}

+ +

Prueba a buscar diferentes valores de las siguientes propiedades y escribe reglas CSS que se apliquen a diferentes elementos HTML:

+ + + +

@rules

+ +

Las @rules (leído "at-rules" en inglés) dan al CSS algunas instrucciones sobre cómo comportarse. Algunas @rules son simples, con el nombre de la regla y un valor. Por ejemplo, para importar una hoja de estilo adicional a tu hoja de estilo CSS principal, puedes usar @import:

+ +
@import 'styles2.css';
+ +

Una de las @rules más comunes con las que te encontrarás es @media, que permite usar consultas a medios para aplicar CSS solo cuando se dan ciertas condiciones (por ejemplo, cuando la resolución de la pantalla supera un valor determinado o la anchura supera un valor concreto).

+ +

En el CSS que se muestra a continuación, tenemos una hoja de estilo que le da al elemento <body> un color de fondo rosado. Sin embargo, luego usamos @media para crear una sección de nuestra hoja de estilo que solo se aplicará en los navegadores con una ventana gráfica de más de 30em de ancho. Si el navegador es más ancho que 30em, el color de fondo será azul.

+ +
body {
+  background-color: pink;
+}
+
+@media (min-width: 30em) {
+  body {
+    background-color: blue;
+  }
+}
+ +

Encontrarás otras @rules a lo largo de estas lecciones.

+ +

Prueba a añadir una consulta a medios en tu CSS que cambie los estilos según el ancho de la ventana gráfica. Cambia el ancho de la ventana de tu navegador para ver el resultado.

+ +

Abreviaturas

+ +

Algunas propiedades como {{cssxref("font")}}, {{cssxref("background")}}, {{cssxref("padding")}}, {{cssxref("border")}} y {{ cssxref("margin")}} se llaman propiedades abreviadas. Esto se debe a que permiten establecer varios valores de propiedad en una sola línea, lo que ahorra tiempo y ordena el código.

+ +

Por ejemplo, esta línea:

+ +
/* En propiedades abreviadas con 4 valores, como margin y padding (relleno), los valores se aplican
+   según el orden: arriba, derecha, abajo e izquierda (en sentido horario desde la parte superior). También hay otros
+   tipos de abreviaturas, como las propiedades abreviadas con 2 valores que establecen el relleno/margen,
+   arriba/abajo, y luego izquierda/derecha */
+padding: 10px 15px 15px 5px;
+ +

Hace lo mismo que todas estas juntas:

+ +
padding-top: 10px;
+padding-right: 15px;
+padding-bottom: 15px;
+padding-left: 5px;
+ +

Mientras que esta línea:

+ +
background: red url(bg-graphic.png) 10px 10px repeat-x fixed;
+ +

Hace lo mismo que todas estas juntas:

+ +
background-color: red;
+background-image: url(bg-graphic.png);
+background-position: 10px 10px;
+background-repeat: repeat-x;
+background-scroll: fixed;
+ +

Ahora mismo no pretendemos enseñarlos exhaustivamente: encontrarás muchos ejemplos más adelante en el curso. Te aconsejamos que busques los nombres de las propiedades abreviadas en nuestra referencia CSS para obtener más información.

+ +

Prueba a añadir las declaraciones anteriores a tu CSS para ver cómo afecta al estilo de tu HTML. Experimenta con diferentes valores.

+ +
+

Advertencia: Si bien las propiedades abreviadas a menudo permiten ahorrarte valores, luego restablecerán a sus valores iniciales cualquier valor que no incluyas. Esto asegura que se use un conjunto de valores razonable. Sin embargo, puede resultar confuso si esperas que la propiedad abreviada solo cambie los valores que has introducido.

+
+ +

Comentarios

+ +

Al igual que con el HTML, te recomendamos que hagas comentarios en tu CSS para que te ayuden a comprender cómo funciona su código cuando vuelvas a utilizarlo al cabo de varios meses, así como para ayudar a otros que vayan a trabajar con él a entenderlo.

+ +

Los comentarios en el CSS comienzan con /* y terminan con */. En el bloque de código que encontrarás a continuación, hemos usado comentarios para marcar el inicio de las diferentes secciones de código. Esto es útil para ayudarnos a movernos por la base de código a medida que aumenta: puedes buscar los comentarios en tu editor de código.

+ +
/* con elementos básicos de aplicación de estilo */
+/* -------------------------------------------------------------------------------------------- */
+body {
+  font: 1em/150% Helvética, Arial, sans-serif;
+  padding: 1em;
+  margin: 0 auto;
+  max-width: 33em;
+}
+
+@media (min-width: 70em) {
+  /* Prestemos especial atención al tamaño de fuente global. En una pantalla o una ventana grande,
+     aumentamos el tamaño de la fuente para conseguir una mejor legibilidad */
+  body {
+    font-size: 130%;
+  }
+}
+
+h1 {font-size: 1.5em;}
+
+/* Familiarización con algunos elementos anidados específicos en el DOM */
+/* -------------------------------------------------------------------------------------------- */
+div p, #id:first-line {
+  background-color: red;
+  border-radius: 3px;
+}
+
+div p {
+  margin: 0;
+  padding: 1em;
+}
+
+div p + p {
+  padding-top: 0;
+}
+ +

Los comentarios también son útiles para comentar temporalmente ciertas partes del código con fines de prueba, por ejemplo, si tratas de encontrar qué parte de tu código causa un error. En el siguiente ejemplo, hemos comentado las reglas para el selector .special.

+ +
/*.special {
+  color: red;
+}*/
+
+p {
+  color: blue;
+}
+ +

Añade algunos comentarios al CSS para acostumbrarte a usarlos.

+ +

Espacio en blanco

+ +

Por espacio en blanco nos referimos los espacios en sí, tabuladores y retornos de carro o intros. De la misma manera que el HTML, el navegador ignora el espacio en blanco dentro del CSS. El valor del espacio en blanco es que puede mejorar la legibilidad.

+ +

En el siguiente ejemplo, cada declaración (y el principio/fin de regla) está en una línea propia; esta es posiblemente una buena forma de escribir el CSS, ya que facilita el mantenimiento y la comprensión:

+ +
body {
+  font: 1em/150% Helvética, Arial, sans-serif;
+  padding: 1em;
+  margin: 0 auto;
+  max-width: 33em;
+}
+
+@media (min-width: 70em) {
+  body {
+    font-size: 130%;
+  }
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+div p,
+#id:first-line {
+  background-color: red;
+  border-radius: 3px;
+}
+
+div p {
+  margin: 0;
+  padding: 1em;
+}
+
+div p + p {
+  padding-top: 0;
+}
+
+ +

Podrías escribir exactamente el mismo CSS eliminando la mayoría de los espacios en blanco; este bloque de código es funcionalmente idéntico al primer ejemplo, pero seguro que estarás de acuerdo en que resulta algo más difícil de leer:

+ +
body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;}
+@media (min-width: 70em) { body {font-size: 130%;} }
+
+h1 {font-size: 1.5em;}
+
+div p, #id:first-line {background-color: red; border-radius: 3px;}
+div p {margin: 0; padding: 1em;}
+div p + p {padding-top: 0;}
+
+ +

La manera que elijas para disponer el código suele ser una preferencia personal, aunque cuando comiences a trabajar en equipo es posible que encuentres que el equipo ya tiene su propia guía de estilo que especifica una convención acordada a seguir.

+ +
+

Importante: Aunque los valores de las declaraciones CSS se separan por espacios, los nombres de propiedad nunca tienen espacios.

+
+ +

Por ejemplo, las siguientes declaraciones de CSS son válidas:

+ +
margin: 0 auto;
+padding-left: 10px;
+ +

Pero las siguientes no lo son:

+ +
margin: 0auto;
+padding- left: 10px;
+ +

¿Ves los errores de espaciado? 0auto no se reconoce como un valor válido para la propiedad de margin (0 y auto son dos valores separados) y el navegador no reconoce padding- como una propiedad válida. El valor correcto de propiedad (padding-left) se ha separado por un espacio perdido.

+ +

Debes asegurarte siempre de separar los valores distintos entre sí por al menos un espacio, pero mantén los nombres de las propiedades y los valores de las propiedades juntos.

+ +

Prueba a jugar con los espacios en blanco de tu CSS y observa qué es lo que se rompe y lo que no.

+ +

¿Qué sigue?

+ +

Resulta útil entender un poco cómo el navegador toma tu HTML y tu CSS y los convierte en una página web, razón por la cual en el próximo artículo (Cómo funciona el CSS) veremos ese proceso.

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}

+ +

En este modulo

+ +
    +
  1. ¿Qué es el CSS?
  2. +
  3. Empezar con el CSS
  4. +
  5. Cómo se estructura el CSS
  6. +
  7. Cómo funciona CSS
  8. +
  9. Pon en práctica tus conocimientos nuevos
  10. +
diff --git a/files/es/learn/css/first_steps/index.html b/files/es/learn/css/first_steps/index.html new file mode 100644 index 0000000000..0213277d94 --- /dev/null +++ b/files/es/learn/css/first_steps/index.html @@ -0,0 +1,52 @@ +--- +title: Primeros pasos en CSS +slug: Learn/CSS/First_steps +tags: + - Aprender + - CSS + - Principiante + - modulo + - primeros pasos +translation_of: Learn/CSS/First_steps +--- +
{{LearnSidebar}}
+ +

CSS (Cascading Style Sheets - en español Hojas de Estilo en Cascadas) es usado para darle estilo y diseño a las páginas Web — por ejemplo, para cambiar la fuente de letra, color, tamaño y el espaciado de tu contenido; dividir en múltiples columnas, o agregar animaciones y otras propiedades decorativas. Este modulo provee un inicio suave para tu ruta de aprendizaje hacia el dominio de CSS con su funcionamiento básico, como luce su sintaxis, y cómo puedes comenzar a utilizarlo y añadir estilo a HTML.

+ +

Prerrequisitos

+ +

Antes de comenzar este módulo, deberías:

+ +
    +
  1. Estar familiarizado y tener conocimiento básico sobre el uso de computadores e internet básico (p.ej. navegando, consumiendo contenido en Internet.)
  2. +
  3. Un entorno básico de trabajo configurado, como se detalla en la sección de Instalación de software básico, y saber como crear y administrar archivos, o lo puedes ver en el módulo Manejando los archivos.
  4. +
  5. Conocimiento básico de HTML, como se muestra en Introducción a HTML.
  6. +
+ +
+

Nota: Si estás trabajando en un computador/tabla/otro dispositivo en el cual no puedes crear o almacenar tus propios archivos, podrías probar (la mayoría) de los ejemplos de código en un editor de código en línea como JSBinThimble.

+
+ +

Guías

+ +

Este módulo contiene los siguientes artículos, que te guiarán a través de toda la teoría básica de CSS, y te proveerá oportunidades para comprobar algunas de tus habilidades.

+ +
+
¿Qué es CSS?
+
{{Glossary("CSS")}} (Cascading Style Sheets) te permite crear páginas Webs atractivas, pero ¿Cómo funciona por debajo? Este artículo explica que es CSS, con ejemplos simples de sintaxis, y cubre algunos temas clave sobre este lenguaje.
+
Empezar con CSS
+
En este artículo se tomarná un documento HTML simple y se le aplicará CSS, aprendiendo algunas cosas prácticas mientras lo haces.
+
Como se estructura CSS
+
Ahora que sabes que es CSS y de su uso básico, es momento de sumergirnos un poco más dentro de la estructura del propio lenguaje. Ya hemos conocido muchos de los conceptos discutidos aquí; puedes volver a este resumen en el futuro si necesitas reforzar conocimientos o si tienes dudas sobre algun concepto.
+
Como trabaja CSS
+
Hemos aprendido lo básico de CSS, para que es y como escribir una hoja de estilo sencilla. En esta lección echaremos un vistazo a como los navegadores web reciben CSS y HTML y los convierten en una página web.
+
Usando tu nuevo conocimiento
+
Con las cosas que has aprendido en las últimas lecciones encontrarás que usando CSS puedes editar el formato de documentos de texto simple, para agregarles tu propio estilo. Este artículo te da la oportunidad de hacerlo.
+
+ +

Ver también

+ +
+
Conocimiento práctico intermedio Web 1: Introducción a CSS (en Inglés) 
+
Un excelente curso de Mozilla foundation que explora y prueba muchas de las habilidades de las que se habla en el módulo de Introducción al CSS. Aprende acerca de como agregar estilo a los elementos HTML en una página web, selectores CSS, atributos, y valores.
+
diff --git "a/files/es/learn/css/first_steps/qu\303\251_es_css/index.html" "b/files/es/learn/css/first_steps/qu\303\251_es_css/index.html" new file mode 100644 index 0000000000..eb4f8e8a8a --- /dev/null +++ "b/files/es/learn/css/first_steps/qu\303\251_es_css/index.html" @@ -0,0 +1,127 @@ +--- +title: ¿Qué es el CSS? +slug: Learn/CSS/First_steps/Qué_es_CSS +tags: + - Beginner + - CSS + - Introduction to CSS + - Learn + - Modules + - Specifications + - Syntax +translation_of: Learn/CSS/First_steps/What_is_CSS +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}
+ +

Las hojas de estilo en cascada ({{Glossary("CSS")}}, cascading style sheets) permiten crear páginas web atractivas. Pero ¿cómo funcionan realmente? En este artículo explicaremos qué es el CSS con un ejemplo de sintaxis sencillo y describiremos algunos términos clave sobre este lenguaje.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener instalado el software básico, conocimientos básicos de cómo trabajar con archivos y nociones de HTML (véase Introducción al HTML).
Objetivo:Aprender qué es CSS.
+ +

En el módulo Introducción al HTML, exponemos qué es el HTML y cómo se usa para definir documentos destinados a leerse en un navegador web. Los títulos se verán más grandes que el texto y los párrafos empezarán en una línea nueva y habrá un espacio entre ellos. Los enlaces aparecerán en un color diferente y subrayados para distinguirlos del resto del texto. Vienen predeterminados por el navegador y, en la práctica, son estilos muy básicos que el navegador aplica al HTML para asegurarse, básicamente, de que sean legibles incluso si el autor de la página no especifica un estilo explícito.

+ +

Los estilos predeterminados utilizados por el navegador

+ +

Sin embargo, Internet sería un lugar muy aburrido si todas las páginas web se vieran así. Usando CSS se pueden controlar con precisión cómo se ven los elementos HTML en el navegador, que presentará para las etiquetas de marcado el diseño que cada uno desee.

+ +

¿Para qué sirve el CSS?

+ +

Como hemos mencionado, el CSS es un lenguaje informático que especifica cómo se presentan los documentos a los usuarios: cómo se diseñan, compaginan, etc.

+ +

Un documento suele ser un archivo de texto estructurado con un lenguaje de marcado: {{Glossary("HTML")}} es el más común, pero también existen otros como {{Glossary("SVG")}} o {{Glossary("XML")}}.

+ +

Presentar un documento a un usuario significa convertirlo en un formulario que el público pueda utilizar. Los {{Glossary("Navegador", "navegadores")}}, como por ejemplo {{Glossary("Mozilla Firefox", "Firefox")}}, {{Glossary("Google Chrome", "Chrome")}} o {{Glossary("Microsoft Edge", "Edge")}}, están diseñados para presentar documentos visualmente en una pantalla de ordenador, un proyector o una impresora.

+ +
+

Nota: Un navegador también recibe el nombre de {{Glossary("Agente de usuario", "agente de usuario")}}, que consiste en un programa informático que representa a una persona dentro del sistema. Los navegadores son el modelo principal de agente de usuario en el que pensamos cuando hablamos de CSS, pero no son el único. Hay otros documentos de usuario disponibles, como los que convierten documentos HTML y CSS en PDF para imprimir.

+
+ +

El CSS se puede usar para estilos de texto muy básicos como, por ejemplo, cambiar el color y el tamaño de los encabezados y los enlaces. Se puede utilizar para crear un diseño, como podría ser convertir una columna de texto en una composición con un área de contenido principal y una barra lateral para información relacionada. Incluso se puede usar para crear efectos de animación. Echa un vistazo a los enlaces de este párrafo para ver ejemplos específicos.

+ +

Sintaxis del CSS

+ +

El CSS es un lenguaje basado en reglas: cada usuario define las reglas que especifican los grupos de estilos que van a aplicarse a elementos particulares o grupos de elementos de la página web. Por ejemplo: «Quiero que el encabezado principal de mi página se muestre en letras grandes de color rojo».

+ +

El código siguiente muestra una regla CSS muy simple que proporcionaría el estilo descrito en el párrafo anterior:

+ +
h1 {
+    color: red;
+    font-size: 5em;
+}
+ +

La regla se abre con un {{Glossary("CSS Selector", "selector")}}. Este selecciona el elemento HTML que vamos a diseñar. En este caso, diseñaremos encabezados de nivel uno ({{htmlelement ("h1")}}).

+ +

Luego tenemos un conjunto de llaves { }. Entre estas habrá una o más declaraciones, que tomarán la forma de pares de propiedad y valor. Cada par especifica cada una de las propiedades de los elementos seleccionados y el valor que queremos dar a esa propiedad.

+ +

Antes de los dos puntos, tenemos la propiedad; y después, el valor. Las {{Glossary("property/CSS", "propiedades")}} CSS admiten diferentes valores, dependiendo de qué propiedad se esté especificando. En el ejemplo anterior, tenemos la propiedad color, que puede tomar varios valores de color. También tenemos la propiedad de font-size, que puede tomar varias unidades de tamaño como valor.

+ +

Una hoja de estilo CSS contendrá muchas de estas reglas, escritas una tras otra.

+ +
h1 {
+    color: red;
+    font-size: 5em;
+}
+
+p {
+    color: black;
+}
+ +

Algunos valores se aprenden rápidamente, mientras que otros deberán buscarse. Las páginas de propiedades individuales que hay en el proyecto MDN proporcionan una forma rápida de buscar propiedades y sus valores en caso de olvidarlos o desear saber qué más se puede usar como valor.

+ +
+

Nota: Puedes encontrar enlaces a todas las páginas de las propiedades CSS (junto con otras características CSS) enumeradas en la referencia CSS del proyecto MDN. Alternativamente, deberías acostumbrarte a buscar «mdn css-feature-name» en tu motor de búsqueda favorito siempre que necesites obtener más información sobre una función CSS. Por ejemplo, intenta buscar «mdn color» y «mdn font-size».

+
+ +

Módulos CSS

+ +

Como hay tantas cosas que se podrían diseñar usando CSS, el lenguaje se divide en módulos. Verás referencias a estos módulos a medida que explores en MDN y observarás que muchas de las páginas de documentación están organizadas en torno a un módulo en particular. Por ejemplo, puedes echar un vistazo a la referencia MDN del módulo Fondos y bordes para averiguar cuál es su propósito, qué otras propiedades y características diferentes contiene. También encontrarás enlaces a la especificación CSS que define la tecnología (ver más abajo).

+ +

En esta fase, no debes preocuparte demasiado sobre cómo se estructura el CSS, sin embargo, puede facilitarte la búsqueda de información si, por ejemplo, sabes que es probable que cierta propiedad se encuentre entre otras similares y, por lo tanto, en la misma especificación. 

+ +

Volvamos al módulo de Fondos y bordes para un ejemplo específico: puedes pensar que tiene lógica que las propiedades background-color y border-color se definan en este módulo. Y llevas toda la razón.

+ +

Especificaciones CSS

+ +

Todas las tecnologías de estándares web (HTML, CSS, JavaScript, etc.) se definen en extensos documentos denominados especificaciones, publicados por organizaciones de estándares (como {{glossary("W3C")}}, {{glossary("WHATWG")}}, {{glossary("ECMA")}} o {{glossary("Khronos")}}) que definen con precisión cómo se supone que deben comportarse esas tecnologías.

+ +

El caso de CSS no es diferente: lo desarrolla un grupo del W3C llamado CSS Working Group. Este grupo está compuesto por representantes de proveedores de navegadores y otras compañías interesadas en CSS. También hay otras personas, conocidas como expertos invitados, que actúan como voces independientes y no están vinculados a ninguna organización.

+ +

El CSS Working Group desarrolla o especifica características nuevas del CSS. Algunas veces lo hacen porque un navegador en particular está interesado en alguna capacidad, otras porque los diseñadores y desarrolladores web piden una característica, y otras porque el grupo ha identificado un requisito. El CSS está en desarrollo constante y todos los días presenta nuevas características disponibles. Sin embargo, un elemento clave sobre el CSS es que toda la comunidad se esfuerza mucho en no cambiar nunca nada que pueda perjudicar los sitios web antiguos. ¡Un sitio web creado en el año 2000, que utiliza el poco CSS disponible que había en ese momento, aún debería poder utilizarse hoy en día!

+ +

Como recién llegado al CSS, es probable que encuentres las especificaciones abrumadoras: están destinadas a que los ingenieros las utilicen para implementar soporte de sus características en los agentes de usuario en que trabajan, no para que lo lean los desarrolladores web para comprender el CSS. Muchos desarrolladores experimentados preferirán consultar la documentación disponible en MDN u otros tutoriales. Sin embargo, vale la pena saber que existen y comprender la relación que hay entre el CSS que estás utilizando, el soporte del navegador (ver más abajo) y las especificaciones.

+ +

Soporte del navegador

+ +

Una vez se ha especificado el CSS, solo es útil en el desarrollo de páginas web si uno o más navegadores lo han implementado. Esto significa que el código se ha escrito para convertir las instrucciones que se especifican en nuestro archivo CSS en algo que se pueda mostrar en pantalla. Veremos este proceso más en profundidad en el artículo Cómo funciona el CSS. Es inusual que todos los navegadores puedan implementar una misma característica al mismo tiempo, por lo que suele haber una brecha en la que se pueden usar algunas partes del CSS en algunos navegadores pero no en otros. Por este motivo, es útil poder verificar el estado de implementación. En cada una de las páginas de propiedades que hay en la MDN se puede ver el estado de la propiedad de interés, por lo que se puede saber si será posible utilizarla en un sitio web.

+ +

Lo que sigue es el gráfico de datos de compatibilidad para la propiedad CSS font-family.

+ +

{{Compat("css.properties.font-family")}}

+ +

¿Qué viene ahora?

+ +

Ahora que comprendes mínimamente qué es el CSS, pasemos a Comenzar con CSS, donde puedes empezar a escribir algo de CSS tú mismo.

+ +

{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}

+ +

En este módulo

+ +
    +
  1. ¿Qué es el CSS?
  2. +
  3. Comenzar con CSS
  4. +
  5. Cómo se estructura el CSS
  6. +
  7. Cómo funciona el CSS
  8. +
  9. Pon en práctica tus conocimientos nuevos
  10. +
diff --git a/files/es/learn/css/first_steps/usa_tu_nuevo_conocimiento/index.html b/files/es/learn/css/first_steps/usa_tu_nuevo_conocimiento/index.html new file mode 100644 index 0000000000..bff4f103bf --- /dev/null +++ b/files/es/learn/css/first_steps/usa_tu_nuevo_conocimiento/index.html @@ -0,0 +1,100 @@ +--- +title: Usa tu nuevo conocimiento +slug: Learn/CSS/First_steps/Usa_tu_nuevo_conocimiento +tags: + - Aprendizaje + - CSS + - Principiante +translation_of: Learn/CSS/First_steps/Using_your_new_knowledge +--- +

{{LearnSidebar}}{{PreviousMenu("Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}

+ +

Con las cosas que has aprendido en las últimas lecciones, puedes darle formato a documentos de texto simple utilizando CSS para agregar tu propio estilo a ellos. Esta evaluación te da una posibilidad de hacer eso.

+ + + + + + + + + + + + +
Prerrequisitos:Antes de intentar esta evaluación, deberías haber trabajado a través del módulo de CSS básico, y también comprender HTML básico (estudia la Introducción a HTML).
Objetivo:Utilizar algún CSS y probar conocimiento recién adquirido.
+ +

Punto de partida

+ +

Puedes trabajar en el editor en vivo más abajo, o puedes descargar el punto de partida para trabajar con tu propio editor. Esta es una página HTML, con el inicio del CSS en el <head> del documento. Si prefieres, puedes mover este CSS a un archivo separado cuando crees el ejemplo en tu computador. Alternativamente, puedes usar una herramienta en línea como CodePenjsFiddle, o Glitch para trabajar en las tareas.

+ +
+

Nota: Si te atascas, pide ayuda — mira la sección Evaluación o ayuda adicional al final de esta página.

+
+ +

Trabajando con CSS

+ +

Los siguientes ejemplos muestran una biografía, que ha sido estilizada usando CSS. Las propiedades CSS que se han utilizado son las siguientes - cada una enlaza a su página de propiedades en MDN, que te entregará más ejemplos de su uso:

+ + + +

Se ha usado una mezcla de selectores, elementos de estilo como <h1> y <h2>, y también una clase para el título del trabajo.

+ +

Usa CSS para cambiar el aspecto de esta biografía, cambiando los valores de las propiedades iniciales.

+ +
    +
  1. Coloca en rosado el nivel <h1>, usando el color CSS hotpink.
  2. +
  3. Da al encabezado un {{cssxref("border-bottom")}} de 10px con puntos (dotted), que use el color CSS purple.
  4. +
  5. Coloca en cursiva el <h2>.
  6. +
  7. Al ul utilizado para los detalles de contacto un  {{cssxref("background-color")}}  #eeeeee, y un {{cssxref("border")}} de 5px solid purple. Usa algo de {{cssxref("padding")}} para empujar el texto lejos del borde.
  8. +
  9. Cambia los enlaces a verde cuando pase el cursor sobre ellos.
  10. +
+ +

Deberías conseguir algo parecido a esta página:

+ +

Screenshot of how the example should look after completing the assessment.

+ +

Posteriormente intenta buscar algunas propiedades no mencionadas en esta página en la referencia de CSS de MDN y ¡arriésgate!.

+ +

Recuerda que no existen respuestas equivocadas acá - En esta etapa en tu aprendizaje puedes tener un poco de diversión.

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/biog.html", '100%', 1600)}} 

+ +

Evaluación o ayuda adicional

+ +

Si deseas que tu trabajo sea evaluado, o estás atorado y quieres solicitar ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea con capacidad de compartir como CodePenjsFiddle, o Glitch.
  2. +
  3. Escribe una publicación solicitando evaluacion y/o ayuda en el MDN Discourse forum Learning category. Tu publicación debería incluir: +
      +
    • Un título descriptivo como "Requiero evaluacion para Primeros pasos en CSS".
    • +
    • Detalles de lo que ya has intentado, y que te gustaría que hiciéramos, por ejemplo, si estas atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que quieres que sea evaluado o por el que necesitas ayuda en un  editor en linea con capacidad de compartir (como se mencionó en el paso 1 más arriba). Esta es una buena práctica  - Es muy dificil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la tarea o página de evaluacion actual, para que podamos encontrar la pregunta con la cual necesitas ayuda.
    • +
    +
  4. +
+ +

¿Qué sigue?

+ +

Felicitaciones por completar este primer modulo!. Deberías tener un buen entendimiento general de CSS, y ser capaz de comprender bastante de los que está sucediendo en una hoja de estilo. En el módulo siguiente, bloques de construccion CSS, revisaremos en profundidad algunas áreas clave.

+ +

{{PreviousMenu("Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}

+ +

En este módulo

+ +
    +
  1. ¿Qué es CSS?
  2. +
  3. Empezando con CSS
  4. +
  5. Cómo se estructura el CSS
  6. +
  7. Cómo funciona CSS
  8. +
  9. Usa tu nuevo conocimiento
  10. +
diff --git a/files/es/learn/css/index.html b/files/es/learn/css/index.html new file mode 100644 index 0000000000..ce384edeb2 --- /dev/null +++ b/files/es/learn/css/index.html @@ -0,0 +1,63 @@ +--- +title: CSS +slug: Learn/CSS +tags: + - CSS + - Codificación + - Depuración + - Necesidades + - Principiante + - Tema + - concreción + - longitud +translation_of: Learn/CSS +--- +
{{LearnSidebar}}
+ +

Las Hojas de estilo en cascada (del ingles Cascading Stylesheets {{glossary("CSS")}}) es la siguiente tecnología que aprenderemos después de {{glossary("HTML")}}. Mientras que HTML se utiliza para definir la estructura y la semántica del contenido, CSS se usa para darle estilo y posicionarlo visualmente. CSS se puede usar, por ejemplo, para cambiar la fuente, el color, el tamaño y el espaciado del contenido, para formar multiples columnas, añadir animaciones y otros elementos decorativos.

+ +

Itinerario de aprendizaje

+ +

Antes de empezar con CSS deberemos conocer los fundamentos de HTML. Podemos trabajar este contenido en introducción a HTML para posteriormente aprender:

+ + + +

Se recomienda aprender HTML y CSS al mismo tiempo, trabajando de forma conjunta ambas disciplinas. CSS aporta un valor añadido a HTML y no podrás aprender CSS sin controlar HTML.

+ +

Antes de comenzar con este tema, deberemos tener conocimientos básicos sobre el uso de ordenadores y sobre el uso pasivo de la Web (navegar y consumir contenido). Es recomendable tener configurado un entorno de desarrollo como el detallado en Instalación de software básico, y saber crear y gestionar archivos como se detalla en Manejando archivos — ambos forman parte del módulo Primeros pasos en la Web para principiantes.

+ +

Se recomienda trabajar el módulo Primeros pasos en la Web antes de entrar a este tema, aunque no es completamente necesario; gran parte de lo tratado en el artículo de CSS básico también se trata en el módulo de introducción a CSS, aunque con mucho más detalle.

+ +

Módulos

+ +

Este tema contiene los siguientes módulos en el orden recomendado de aprendizaje. Recomendamos comenzar por el primero.

+ +
+
Introducción a CSS
+
Este módulo explica los conceptos básicos sobre el funcionamiento de CSS, incluyendo selectores y propiedades, escritura de reglas CSS, aplicación de CSS a HTML, cómo especificar longitud, color y otras unidades en CSS, organización en cascada y herencia, conceptos de encajonado básicos y depuración de CSS.
+
Estilo del texto
+
Aquí veremos cómo aplicar estilos al texto, tipos de letra, negrita, cursiva, espaciado, interlineado y sombreado, entre otras funciones relativas al texto. Terminaremos el módulo aplicando tipos a nuestra página, configurando listas y enlaces.
+
Estilos por cajas
+
A continuación veremos la aplicación de estilos por cajas, fundamental en el diseño de páginas web. En este módulo analizaremos el modelo de cajas para después aprender a controlar el diseño de las cajas ajustando rellenos, marcos y márgenes, personalizando colores de fondo, imágenes y otras características, además de divertidas funcionalidades como el sombreado y los filtros sobre las cajas.
+
Diseño CSS
+
Llegados a este punto ya conocemos lo básico de CSS, como darle estilo al texto, y cómo dar estilo y manipular el contenido de las cajas. Es momento de ver cómo ubicar las cajas correctamente con respecto a la ventana de visualización y a otra. Hemos cubierto los requisitos necesarios para poder meternos de lleno en el diseño CSS, ver diferentes ajustes de visualización, metodos tradicionales de diseño con pivotes y posicionamiento, y nuevas herramientas de diseño como flexbox.
+
Diseño Adaptable (RBD Responsive Web Design)
+
Con la gran variedad de dispositivos capaces de navegar por la Web actualmente, el diseño web adaptable (RWD) es una habilidad imprescindible para el diseño web. En este módulo veremos principios básicos y herramientas de RWD, como aplicar diferentes CSS a un documento dependiendo de las características del dispositivo como el ancho de la pantalla, la orientación y la resolución; veremos las tecnologías disponibles para mostrar videos e imágenes dependiendo de estas características.
+
+ +

Resolución de problemas con CSS

+ +

Uso de CSS para resolver problemas comunes proporciona vínculos a secciones que explican cómo usar CSS para resolver problemas comunes cuando se está creando una página web.

+ +
+

Ver También

+ +
+
CSS en MDN
+
Principal entrada para la documentación de CSS en MDN, donde encontrarás documentación detallada de todas las funcionalidades del lenguaje CSS. ¿Quieres saber todos los valores posibles de una propiedad? Este es tu sitio.
+
+
diff --git a/files/es/learn/css/introduction_to_css/fundamental_css_comprehension/index.html b/files/es/learn/css/introduction_to_css/fundamental_css_comprehension/index.html new file mode 100644 index 0000000000..b53db2df02 --- /dev/null +++ b/files/es/learn/css/introduction_to_css/fundamental_css_comprehension/index.html @@ -0,0 +1,117 @@ +--- +title: Comprensión de los fundamentos de CSS +slug: Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension +tags: + - CSS + - Estilo + - Evaluación + - Modelo de Caja + - Principiante + - Selectores + - Sintaxis + - comentários + - reglas +translation_of: Learn/CSS/Building_blocks/Fundamental_CSS_comprehension +--- +
+
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}
+ +

Has avanzado mucho en este módulo, debes sentirte orgulloso de haber llegado hasta el final. El último paso antes de terminar es intentar el examen del módulo — que incluye completar varios ejercicios para crear el último diseño — una tarjeta de presentación/de jugador/perfil de redes sociales.

+ + + + + + + + + + + + +
Prerrequisitos:Antes de intentar esta evaluación, debería haber revisado todos los artículos en este módulo.
Objetivo:Probar la comprensión de los fundamentos de la teoría, sintaxis y mecánica de CSS.
+ +

Punto de Partida

+ +

Para comenzar esta evaluación, debes:

+ + + +
+

Nota: Alternativamente, se puede utilizar un sitio como  JSBinThimble para hacer la evaluación. Puede pegar el HTML y completar el CSS en uno de estos editores en línea, y usar  esta URL para apuntar el elemento <img> al archivo de imagen. Si el editor en línea que estás usando no tiene un panel CSS separado, no dudes en ponerlo en un elemento <style> en el encabezado del documento.

+
+ +

Resumen del Proyecto

+ +

Se le ha proporcionado un poco de HTML puro y una imagen, y necesitas escribir el CSS necesario para darle estilo a una pequeña tarjeta de presentación en línea, que tal vez pueda servir como una tarjeta de jugador o de perfil en redes sociales. Las siguientes secciones describen lo que debes hacer.

+ +

Configuración básica:

+ + + +

Encargandonos de los selectores y conjuntos de reglas proporcionados:

+ + + +

Nuevos conjuntos de reglas que necesitas escribir:

+ + + +

Otras cosas en las que pensar:

+ + + +

Consejos y Sugerencias

+ + + +

Ejemplo

+ +

La siguiente captura de pantalla muestra un ejemplo de cómo debe ser el diseño terminado:

+ +

A view of the finished business card, show a reader header and footer, and a darker center panel containing the main details and image.

+ +

 

+ +

Evaluación

+ +

Si estás siguiendo esta evaluación como parte de un curso organizado, deberías ser capaz de entregar tu trabajo a tu profesor/mentor para que lo califique. Si eres autodidacta, entonces puedes obtener la guía de puntuación fácilmente preguntando en el hilo del Discurso del Área de Aprendizaje, o en el canal IRC #mdn en Mozilla IRC. Haz el ejercicio primero - ¡No hay nada que ganar haciendo trampa!

+ +

{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}

+
diff --git a/files/es/learn/css/styling_text/fuentes_web/index.html b/files/es/learn/css/styling_text/fuentes_web/index.html new file mode 100644 index 0000000000..7bfa162217 --- /dev/null +++ b/files/es/learn/css/styling_text/fuentes_web/index.html @@ -0,0 +1,197 @@ +--- +title: Fuentes web +slug: Learn/CSS/Styling_text/Fuentes_web +translation_of: Learn/CSS/Styling_text/Web_fonts +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}
+ +

En el primer artículo del módulo, exploramos las características básicas del CSS disponibles para aplicar estilos a tipos de letra y al texto. En este artículo vamos a ir más lejos: exploraremos en detalle las tipografías web, que permiten que te descargues tipos de letra personalizados junto con tu página web para lograr un estilo de texto más variado y personalizado.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conceptos básicos de HTML (véase Introducción al HTML) y de CSS (véase Introducción al CSS), texto CSS y los fundamentos de la fuente.
Objetivo:Aprender a aplicar tipos de letra a una página web, ya sea desde un servicio de terceros o desde tu código.
+ +

Resumen de las familias de tipos de letra

+ +

Como observamos en el artículo Texto y tipos de letra, puedes controlar los tipos de letra que aplicas a tu HTML con la propiedad {{cssxref ("font-family")}}. Este atributo toma uno o más nombres de familia de tipos de letra y el navegador recorre esta lista hasta que encuentra un tipo de letra disponible en el sistema en el que se ejecuta:

+ +
p {
+  font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
+}
+ +

Este sistema funciona bien, pero las opciones de tipo de letra tradicionales de los desarrolladores web eran limitadas. Solo hay un puñado de tipos de letra que puedes garantizar que están disponibles en todos los sistemas comunes: las llamadas fuentes seguras para la web. Puedes usar la lista de tipos de letra para especificar cuáles prefieres, seguido de alternativas seguras para la web y del tipo de letra predeterminado del sistema. El problema es que esto añade trabajo extra en términos de pruebas para asegurarte de que tus diseños se ven bien con cada tipo de letra, etc.

+ +

Tipografías web

+ +

Hay una alternativa, sin embargo, que funciona muy bien hasta con versiones posteriores a la versión 6 de Internet Explorer. Las tipografías web son una función del CSS que te permite especificar los archivos de tipo de letra que se van a descargar junto con tu sitio web a medida que el usuario acceda a ellos, lo que significa que cualquier navegador que admita tipografías web puede disponer de los tipos de letra que especificas. ¡Increíble! Observa a continuación la sintaxis que se necesita.

+ +

En primer lugar, tienes un bloque {{cssxref ("@font-face")}} al comienzo del CSS, que especifica los archivos de los tipos de letra que quieres que se descarguen:

+ +
@font-face {
+  font-family: "myFont";
+  src: url("myFont.woff");
+}
+ +

A continuación, puedes usar el nombre de la familia de tipos de letra especificado en @font-face para aplicar tu tipo de letra personalizado a cualquier elemento que desees:

+ +
html {
+  font-family: "myFont", "Bitstream Vera Serif", serif;
+}
+ +

La sintaxis es un poco más compleja; más adelante la veremos más detalladamente.

+ +

Hay dos cosas importantes a tener en cuenta acerca de las tipografías web:

+ +
    +
  1. Los navegadores admiten diferentes formatos de tipos de letra, por lo que necesitarás más de un formato de tipos de letra para conseguir una compatibilidad decente entre navegadores. Por ejemplo, la mayoría de los navegadores modernos admiten WOFF/WOFF2 (Web Open Font Format, versiones 1 y 2), el formato más eficiente disponible. Pero las versiones antiguas de Internet Explorer solo admiten tipos de letra con formato EOT (Embedded Open Type) y es posible que debas incluir una versión SVG del tipo de letra para soportar versiones antiguas de navegadores iPhone y Android. A continuación te mostraremos cómo generar el código necesario.
  2. +
  3. Generalmente las fuentes no son de uso gratuito. Debes pagar por ellas y/o respetar otras condiciones de licencia, como acreditar al creador del tipo de letra en el código (o en tu sitio web). Los tipos de letra no deben robarse, ni debes utilizarlos sin otorgar a su creador el crédito apropiado.
  4. +
+ +
+

Nota: ¡Los tipos de letra seguros para web como tecnología han sido compatibles con Internet Explorer desde su versión 4!

+
+ +

Aprendizaje activo: Un ejemplo de tipo de letra seguro para web

+ +

Con esto en mente, vamos a construir un ejemplo básico de uso de un tipo de letra seguro para web a partir de los principios básicos. Es difícil hacer un ejemplo de demostración de este aspecto con un ejemplo en vivo incrustado, por lo tanto, nos gustaría que siguieses los pasos que se detallan en las secciones siguientes para que te hagas una idea de cómo funciona el proceso.

+ +

Como punto de partida hay que utilizar los archivos web-font-start.html y web-font-start.css a los que añadir tu código (véase el ejemplo en vivo). Haz una copia de estos archivos en un directorio nuevo de tu equipo. En el archivo web-font-start.css, encontrarás un poco de CSS para trabajar con el aspecto y los tipos de letra básicos del ejemplo.

+ +

Encontrar tipos de letra

+ +

Para este ejemplo, utilizaremos dos tipografías web: una para los títulos de encabezado y otra para el texto base. Para empezar, hay que encontrar los archivos que contienen el tipo de letra. Los tipos de letra se crean en estudios de diseño y se guardan en diversos formatos de archivo. En general, hay tres tipos de sitios donde puedes obtener fuentes:

+ + + +

Vamos a ver algunos tipos de letra. Ve a Font Squirrel y elige dos tipos de letra: uno que te resulte agradable e interesante para los títulos (quizá una buena tipografía de tipo Display o Slab Serif), y otro un poco menos llamativo y más legible para los párrafos. Cuando encuentres los tipos de letra, pulsa el botón de descarga y guarda el archivo en el mismo directorio que los archivos HTML y CSS que guardaste anteriormente. No importa si son TTF (True Type Fonts) u OTF (Open Type Fonts).

+ +

En cada caso, descomprime el paquete de tipos de letra (las tipografías web generalmente se distribuyen en archivos ZIP que contienen los archivos con el tipo de letra y la información de la licencia). En el paquete puede haber más de un archivo con tipos de letra: algunos tipos de letra se distribuyen por familias, con diferentes variantes disponibles, por ejemplo: thin, medium, bold, italic, thin italic, etc. Para este ejemplo, solo queremos que te quedes con un solo archivo de fuente para cada opción.

+ +
+

Nota: En la sección «Encontrar tipos de letra» en la columna de la derecha, puedes hacer clic en las diferentes etiquetas y clasificaciones para filtrar las opciones.

+
+ +

Generar el código

+ +

Ahora deberás generar el código que necesitas (y aplicar el estilo al tipo de letra). Para cada tipo de letra, sigue estos pasos:

+ +
    +
  1. Asegúrate de cumplir con todos los requisitos de la licencia, sobre todo si vas a usarlo en un proyecto comercial y/o en una web.
  2. +
  3. Ve a Webfont Generator de Fontsquirrel.
  4. +
  5. Sube tus dos archivos de tipo de letra con el botón Cargar Fuentes.
  6. +
  7. Marca la casilla de verificación con el texto «Sí, las fuentes que elijo pueden utilizarse legalmente para una página web».
  8. +
  9. Haz clic en Descarga tu paquete.
  10. +
+ +

Una vez que el generador haya finalizado el procesamiento, deberías obtener un archivo ZIP para descargar; guárdalo en el mismo directorio que tus archivos HTML y CSS.

+ +

El código de tu ejemplo de demostración

+ +

En este punto, descomprime el paquete con los tipos de letra web que acabas de generar. En el directorio descomprimido verás tres elementos útiles:

+ + + +

Para implementar estos tipos de letra en tu ejemplo de demostración, sigue estos pasos:

+ +
    +
  1. Cambia el nombre del directorio descomprimido a algo fácil y simple, como fonts.
  2. +
  3. Abre el archivo stylesheet.css y copia los dos bloques @font-face incluidos en tu archivo web-font-start.css. Debes ponerlos en la parte superior, antes de cualquier elemento CSS, ya que los tipos de letra deben importarse antes que los puedas utilizar en tu sitio web.
  4. +
  5. Cada una de las funciones url() apunta a un archivo de tipo de letra que tenemos que importar a nuestro CSS. Necesitamos asegurarnos de que las rutas a los archivos son correctas, así que añade fonts/ al inicio de cada ruta (ajusta la ruta como sea necesario).
  6. +
  7. Ahora puedes usar estos tipos de letra en tu lista de tipos de letra, al igual que cualquier tipo de letra seguro o predeterminado del sistema. Por ejemplo: +
    font-family: 'zantrokeregular', serif;
    +
  8. +
+ +

Con tu ejemplo de demostración, deberías obtener una página con unos agradables tipos de letra. Debido a que los tipos de letra se crean en diferentes tamaños, es posible que tengas que ajustar el tamaño, el espaciado, etc., para conseguir una apariencia más ordenada.

+ +

+ +
+

Nota: Si tienes problemas para lograr que esto funcione, no dudes en comparar tu versión con nuestros archivos terminados, consulta web-font-finished.html y web-font-finished.css (ejecuta el ejemplo terminado en vivo).

+
+ +

Los servicios de tipos de letra en línea

+ +

Los servicios de tipos de letra en línea en general guardan tipos de letra y los proporcionan a los usuarios, por lo que no tienes que preocuparte por escribir el código @font-face, solo necesitas insertar una o dos sencillas líneas de código en tu sitio web para que todo funcione. Los ejemplos incluyen Adobe Fonts y Cloud.typography. La mayoría de estos servicios se basan en suscripciones de pago, con la excepción notable de Google Fonts, un servicio gratuito y muy útil, sobre todo para trabajos de prueba rápida y escritura de ejemplos de demostración.

+ +

La mayoría de estos servicios son fáciles de usar, por lo que no vamos a exponerlos en gran detalle. Vamos a echar un vistazo rápido a las fuentes de Google, para que te hagas una idea. De nuevo, usa copias de web-font-start.html y web-font-start.css como punto de partida.

+ +
    +
  1. Ve a Google Fonts.
  2. +
  3. Usa los filtros del lado izquierdo para indicar los tipos de letra que deseas escoger y elige un par de tipos de letra que te gusten.
  4. +
  5. Para seleccionar una familia de tipos de letra, pulsa el botón ⊕ que encontrarás al lado.
  6. +
  7. Cuando hayas elegido las familias de tipos de letra, pulsa la barra [número] familias seleccionadas que encontrarás en la parte inferior de la página.
  8. +
  9. En la pantalla resultante, primero debes copiar la línea de código HTML que se muestra y pegarla en el encabezado de tu archivo HTML. Ponlo encima del elemento {{HTMLElement("link")}}, de modo que el tipo de letra se importe correctamente antes de intentar utilizarlo en tu CSS.
  10. +
  11. Luego, debes copiar las declaraciones CSS enumeradas en tu CSS según corresponda para aplicar los tipos de letra personalizados a tu HTML.
  12. +
+ +
+

Nota: Puedes encontrar una versión completa en google-font.html y google-font.css, si necesitas comparar tu trabajo con el nuestro (consúltalo en vivo).

+
+ +

@font-face con más detalle

+ +

Vamos a explorar que la sintaxis correspondiente a @font-face que te ha generado Fontsquirrel. Uno de los bloques se verá así:

+ +
@font-face {
+  font-family: 'ciclefina';
+  src: url('fonts/cicle_fina-webfont.eot');
+  src: url('fonts/cicle_fina-webfont.eot?#iefix') format('embedded-opentype'),
+         url('fonts/cicle_fina-webfont.woff2') format('woff2'),
+         url('fonts/cicle_fina-webfont.woff') format('woff'),
+         url('fonts/cicle_fina-webfont.ttf') format('truetype'),
+         url('fonts/cicle_fina-webfont.svg#ciclefina') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+ +

Esto se conoce como «sintaxis @font-face a prueba de balas» desde una publicación de Paul Irish, en los tiempos en que @font-face empezaba a popularizarse (Bulletproof @font-face Syntax). Vamos a ver qué hace:

+ + + +
+

Nota: También puedes especificar los valores particulares {{cssxref ("font-variant")}} y {{cssxref ("font-stretch")}} para tus tipos de letra seguros para web. En los navegadores más nuevos también puedes especificar un valor {{cssxref ("unicode-range")}}, que es un rango de caracteres específicos que debes usar aparte del tipo de letra seguro para web en los navegadores que incluyan esta opción. Solo se descargaran los caracteres especificados y te ahorrarás descargas innecesarias. Creating Custom Font Stacks with Unicode-Range de Drew McLellan proporciona algunas ideas útiles sobre cómo hacer uso de todo esto.

+
+ +

Tipos de letra variables

+ +

Los navegadores disponen hoy de una tecnología de tipos de letra reciente llamada tipos de letra variables: se trata de tipos de letra que permiten incorporar muchas variaciones diferentes de un tipo de letra en un solo archivo, en lugar de tener un archivo separado para cada ancho, grosor o estilo. Es demasiado avanzado para nuestro curso para principiantes, pero si te apetece avanzar y echarles un vistazo, lee nuestra guía de tipos de letra variables.

+ +

Resumen

+ +

Ahora que has leído nuestros artículos sobre nociones de aplicación de estilo al texto, es hora de evaluar cuánto has retenido del módulo a partir de la creación de una composición tipográfica de una página de inicio de una escuela comunitaria.

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/styling_text/fundamentals/index.html b/files/es/learn/css/styling_text/fundamentals/index.html new file mode 100644 index 0000000000..a1fa747e27 --- /dev/null +++ b/files/es/learn/css/styling_text/fundamentals/index.html @@ -0,0 +1,732 @@ +--- +title: Fundamentos de texto y fuentes tipográficas +slug: Learn/CSS/Styling_text/Fundamentals +translation_of: Learn/CSS/Styling_text/Fundamentals +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}
+ +

En este artículo vas a iniciar tu viaje hacia el dominio la aplicación de estilos a textos con {{glossary("CSS")}}. Aquí trataremos en detalle todos los fundamentos básicos del diseño del texto y las fuentes tipográficas, incluyendo la configuración de su grosor, la familia y el estilo de letra, las propiedades abreviadas para los tipos de letra, la alineación del texto, el espaciado entre líneas y letras, y otros efectos.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conceptos básicos de HTML (estudio de Introducción al HTML), conceptos básicos de CSS (estudio de Introducción al CSS).
Objetivo:Aprender las propiedades y técnicas fundamentales necesarias para dar estilo al texto en las páginas web.
+ +

¿Qué implica aplicar estilo a texto en CSS?

+ +

Como ya habrás experimentado en tu trabajo con el HTML y el CSS, el texto incluido en un elemento se dispone dentro de la caja de contenido del elemento. Esta empieza en la parte superior izquierda del área de contenido (o en la esquina superior derecha, en el caso del contenido de los lenguajes RTL, o right-to-left, que se escriben de derecha a izquierda) y fluye hacia el final de la línea. Una vez que llega al final, baja a la línea siguiente y sigue, y luego continúa a la línea siguiente, hasta que todo el contenido se ha ubicado en la caja. El contenido de texto se comporta efectivamente como una serie de elementos en línea, distribuidos en líneas adyacentes entre sí, y sin crear saltos de línea hasta que se llega al final de la línea, a menos que se fuerce un salto de línea manual con el elemento {{htmlelement("br")}}.

+ +
+

Nota: Si el párrafo anterior te parece confuso, no te preocupes: vuelve atrás y revisa el artículo sobre el modelo de caja antes de continuar.

+
+ +

Las propiedades CSS que se usan para aplicar estilo al texto pueden clasificarse generalmente en dos categorías, que veremos por separado en este artículo:

+ + + +
+

Nota: Ten en cuenta que el efecto se aplica sobre todo el texto que hay dentro de un elemento como si fuera una única entidad. No puedes seleccionar y dar estilo a subsecciones de texto, a menos que las delimites con algún elemento apropiado (como {{htmlelement("span")}} o {{htmlelement("strong")}}), o con un pseudoelemento específico para el texto como ::first-letter (selecciona la primera letra del texto de un elemento), ::first-line (selecciona la primera línea del texto de un elemento), o ::selection (selecciona el texto que está resaltado por el cursor).

+
+ +

Tipos de letra

+ +

Veamos las propiedades que permiten definir el estilo del tipo de letra. En este ejemplo aplicaremos algunas propiedades CSS diferentes al mismo ejemplo HTML, que presentamos a continuación:

+ +
<h1>Tommy the cat</h1>
+
+<p>Well I remember it as though it were a meal ago...</p>
+
+<p>Said Tommy the Cat as he reeled back to clear whatever foreign matter
+ may have nestled its way into his mighty throat. Many a fat alley rat
+had met its demise while staring point blank down the cavernous barrel of
+ this awesome prowling machine. Truly a wonder of nature this urban
+predator — Tommy the cat had many a story to tell. But it was a rare
+occasion such as this that he did.</p>
+ +

Puedes ver el ejemplo completo en Github (consulta también el código fuente.)

+ +

Color

+ +

La propiedad {{cssxref("color")}} establece el color del contenido de los elementos seleccionados (que normalmente es texto, pero también puede incluir un par cosas más, como un subrayado o una línea superpuesta al texto con la propiedad {{cssxref("text-decoration")}} ).

+ +

La propiedad color puede admitir cualquier unidad de color CSS, por ejemplo:

+ +
p {
+  color: red;
+}
+ +

Esto mostrará el contenido de los párrafos en color rojo, en lugar del negro que es el estándar por defecto del navegador:

+ + + +

{{ EmbedLiveSample('Color', '100%', 220) }}

+ +

Familia de tipos de letras

+ +

Usamos la propiedad {{cssxref("font-family")}} para definir un tipo de letra diferente para nuestro texto. Esta propiedad indica al navegador el tipo de letra (o una lista de tipos de letra) que debe aplicar a los elementos seleccionados. El navegador solo aplica el tipo de letra si la máquina que accede al sitio web dispone de ella; en caso contrario, simplemente usa el tipo de letra que tiene definido por defecto ({{anch("Default fonts", "default font")}}). Aquí tienes un ejemplo sencillo:

+ +
p {
+  font-family: arial;
+}
+ +

Con esto, todos los párrafos de una página adoptan el tipo de letra Arial, que se encuentra en cualquier ordenador.

+ +

Tipos de letra seguros para la web

+ +

Solo hay un cierto número de tipos de letra que están disponibles en todos los sistemas en general, y que en consecuencia pueden utilizarse sin demasiadas preocupaciones. Son los llamados tipos de letra seguros para la web, o web safe fonts.

+ +

La mayor parte del tiempo, como desarrolladores web deseamos tener un control específico mayor sobre los tipos de letra con que se va a mostrar para mostrar nuestro contenido de texto. El problema está en encontrar una manera de saber de qué tipo de letra dispone el ordenador que se utiliza para acceder a nuestras páginas. No hay manera de saber esto en todos los casos, pero al menos contamos con que los tipos de letra seguros para la web están disponibles en casi todos los sistemas operativos más utilizados (las distribuciones Linux más comunes, Windows, Mac, Android, e iOS).

+ +

La lista de los tipos de letra seguros para la web cambia al ir evolucionando los sistemas operativos, pero es correcto considerar los tipos de letra siguientes como seguros para la web, al menos por ahora (muchos de ellos se han popularizado gracias a la iniciativa Core fonts for the web de Microsoft, de finales de la década de 1990 y principios de la del 2000):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NombreTipo de letra genéricoObservaciones
Arialsans-serifA menudo se considera una buena práctica añadir también Helvética como opción preferida a Arial porque, aunque tienen casi el mismo aspecto y Arial está más ampliamente disponible, se considera que Helvética tiene una forma más agradable.
Courier NewmonospaceAlgunos sistemas operativos cuentan con una versión alternativa (posiblemente más antigua) del tipo de letra Courier New llamado Courier. Se considera una buena práctica usar ambos, con Courier New como la opción preferida.
Georgiaserif
Times New RomanserifAlgunos sistemas operativos cuentan con una versión alternativa (posiblemente más antigua) del tipo de letra Times New Roman llamado Times. Se considera una buena práctica usar ambos, con Times New Roman como la opción preferida.
Trebuchet MSsans-serifHay que tener cuidado al usar este tipo de letra porque no está ampliamente disponible en los sistemas operativos móviles.
Verdanasans-serif
+ +
+

Nota: Entre otros recursos, el sitio cssfontstack.com mantiene una lista de tipos de letra seguros disponibles en los sistemas operativos para Windows y Mac, que puede ayudarte en la toma de decisiones acerca de lo que consideras seguro para tus propósitos.

+
+ +
+

Nota: Hay una manera de descargar un tipo de letra personalizado junto con la página web, que te permite personalizar el uso de los tipos de letra de la manera que desees: web fonts. Esto es un poco más complejo, y lo vamos a exponer más adelante en un artículo independiente del módulo.

+
+ +

Fuentes predeterminadas

+ +

CSS define cinco nombres genéricos para los tipos de letra serifsans-serif, monospace, cursivefantasy. Son muy genéricos y el tipo de letra exacto que se va a utilizar cuando se especifiquen dichos nombres dependerá de cada navegador y puede variar dependiendo del sistema operativo. Representa el peor escenario posible, en el que el navegador tratará de proporcionar al menos una fuente que parezca apropiada. serif, sans-serif y monospace son bastante predecibles y el navegador debería proporcionar algo razonable. Por otra parte, cursive y fantasy son menos predecibles y te recomendamos que las uses con cautela, y vayas probando a medida que avanzas.

+ +

Los cinco nombres se definen de la manera siguiente:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NombreDefiniciónEjemplo
serifTipos de letra que tienen serifas (pequeños adornos, en general en los extremos de los trazos de los caracteres tipográficos)Mi gran elefante rojo
sans-serifTipos de letra que carecen de serifas.Mi gran elefante rojo
monospaceTipos de letra en que cada carácter tiene el mismo ancho; se usan con frecuencia en las listas de sentencias de los códigos de programación.Mi gran elefante rojo
cursiveTipos de letra que intentan emular la letra manuscrita, con trazos fluidos y conectados.Mi gran elefante rojo
fantasyTipos de letra que pensados para ser decorativos.Mi gran elefante rojo
+ +

Listas de tipos de letra

+ +

Ya que no puedes garantizar la disponibilidad de los tipos de letra que deseas utilizar (incluso un tipo de letra seguro para la web podría fallar por alguna razón), puedes proporcionar un lista de tipos de letra para que el navegador tenga diversos tipos de letra entre los que elegir. Consiste simplemente en introducirlo como el valor de font-family, que consistirá en una lista de diversos nombres de tipos de letra separados por comas, por ejemplo.

+ +
p {
+  font-family: "Trebuchet MS", Verdana, sans-serif;
+}
+ +

En tal caso, el navegador comienza al principio de la lista y busca si el primer tipo de letra está disponible en la máquina. Si es así, aplica ese tipo de letra a los elementos seleccionados, y si no, lo intenta con el nombre siguiente de la lista; y así sucesivamente.

+ +

Es una buena idea proporcionar un nombre de tipo de letra genérico al final de la lista para que el navegador pueda al menos proporcionar algo aproximadamente adecuado en el caso de que ninguno de los tipos de letra que deseas esté disponible. Para ilustrar este punto: los navegadores asignan a los párrafos el tipo de letra serif por defecto, que normalmente es Times New Roman, si no hay ninguna otra opción disponible, pero esto no resulta conveniente cuando se espera un tipo de letra sans-serif!

+ +
+

Nota: Los nombres de los tipos de letra que están constituidos por más de una palabra (como Trebuchet MS ) han de ponerse entre comillas, por ejemplo "Trebuchet MS".

+
+ +

Un ejemplo con font-family

+ +

Vamos a introducir en nuestro ejemplo anterior una fuente de tipo sans-serif para los párrafos:

+ +
p {
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

Esto nos da el resultado siguiente:

+ + + +

{{ EmbedLiveSample('Un_ejemplo_con_font-family', '100%', 220) }}

+ +

Tamaño de la letra

+ +

En el artículo sobre Unidades y valores de CSS de nuestro módulo anterior, revisamos las unidades de longitud y tamaño. El tamaño del tipo de letra (establecido con la propiedad {{cssxref("font-size")}}) puede tomar valores medidos en la mayoría de estas unidades (y en otras, como porcentajes). Sin embargo, las unidades más comunes que vas a usar para ajustar el tamaño del texto son:

+ + + +

La propiedad font-size de un elemento se hereda del elemento padre. Todo comienza con el elemento raíz de todo el documento ({{htmlelement("html")}}) cuya propiedad font-size se establece a en 16px como estándar en todos los navegadores. Cualquier párrafo (o cualquier otro elemento que no tenga un tamaño diferente establecido por el navegador) dentro del elemento raíz tendrá un tamaño final de 16px. Otros elementos pueden tener diferentes tamaños predeterminados, por ejemplo un elemento {{htmlelement("h1")}} tiene de manera predeterminada un tamaño establecido de 2em, por lo que tendrá un tamaño final de 32px.

+ +

Las cosas se vuelven más complicadas cuando se empieza a alterar el tamaño del tipo de letra de los elementos anidados. Por ejemplo, si tu página incluye un elemento {{htmlelement("article")}} y estableces un tamaño de fuente de 1.5em (que resultará en un tamaño final de 24px), y luego quieres que los párrafos dentro del elemento <article> tengan un tamaño de letra calculado de 20px, ¿qué valor de unidad em deberías usar?

+ +
<!-- El tamaño de letra base del documento es 16px -->
+<article> <!-- Si mi tamaño de letra es 1.5em -->
+  <p>Mi párrafo</p> <!-- ¿Cómo calculo el tamaño del tipo de letra para que de 20px? -->
+</article>
+ +

Necesitarías establecer el valor en unidades em de 20/24, es decir, 0.83333333 em. El cálculo puede ser complicado, por lo que hay que pensarlo bien a la hora de aplicar estilo a las cosas. Lo mejor es usar unidades rem donde se pueda, porque simplifican las cosas, y evitar establecer un tamaño de letra concreto para los elementos del contenedor, siempre que sea posible.

+ +

Un ejemplo sencillo de definición de tamaños

+ +

Al dimensionar el texto, en general es una buena idea establecer el tamaño básico del tipo de letra del documento (font-size) en 10 px, de modo que los cálculos son mucho más fáciles de resolver, puesto que entonces los valores (r)em que necesites son el tamaño del tipo de letra en píxeles dividido por 10, no por 16. Luego de hacer eso, puedes establecer con facilidad los diferentes tamaños de los tipos de letra de tu documento como desees. Es una buena idea hacer una lista de todos los conjuntos de reglas de tamaño de fuente (font-size) en una zona concreta de tu hoja de estilo para que resulten fáciles de encontrar.

+ +

Nuestro nuevo resultado es:

+ + + +
html {
+  font-size: 10px;
+}
+
+h1 {
+  font-size: 2.6rem;
+}
+
+p {
+  font-size: 1.4rem;
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

{{ EmbedLiveSample('Un_ejemplo_sencillo_de_definición_de_tamaños', '100%', 220) }}

+ +

Estilo y cuerpo del tipo de letra, efectos y decoración del texto

+ +

El CSS proporciona cuatro propiedades comunes para alterar el efecto visual / énfasis del texto:

+ + + +

Añadamos un par de estas propiedades a nuestro ejemplo. Nuestro nuevo resultado quedaría como este:

+ + + +
html {
+  font-size: 10px;
+}
+
+h1 {
+  font-size: 2.6rem;
+  text-transform: capitalize;
+}
+
+h1 + p {
+  font-weight: bold;
+}
+
+p {
+  font-size: 1.4rem;
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

{{ EmbedLiveSample('Estilo_y_cuerpo_del_tipo_de_letra_efectos_y_decoración_del_texto', '100%', 220) }}

+ +

Textos sombreados

+ +

Puedes aplicar sombras a tus textos con la propiedad {{cssxref("text-shadow")}}. Esta propiedad puede tomar hasta cuatro valores, como se muestra en ejemplo siguiente:

+ +
text-shadow: 1px 1px 1px red;
+ +

Las cuatro propiedades son las siguientes:

+ +
    +
  1. El desplazamiento horizontal de la sombra desde el texto original; admite la mayoría de las unidades y magnitudes de que dispone CSS, pero lo más habitual es usar px. Es un valor obligatorio.
  2. +
  3. El desplazamiento vertical de la sombra desde el texto original; se comporta básicamente igual que el desplazamiento horizontal, excepto porque mueve la sombra arriba/abajo, y no hacia derecha/izquierda. Es un valor obligatorio.
  4. +
  5. El radio de desenfoque; cuanto más alto es este valor, mayor es la dispersión de la sombra. Si no se incluye este valor, el valor por defecto es 0, y no hay desenfoque. Esta propiedad admite la mayoría de las unidades y magnitudes de que dispone el CSS.
  6. +
  7. El color de base de la sombra, que admite cualquier unidad de color de que dispone CSS. Si no se incluye este valor, el valor predeterminado es negro.
  8. +
+ +
+

Nota: Los valores con desplazamiento positivo mueven la sombra hacia la derecha o hacia abajo, mientras que los valores con desplazamiento negativo, por ejemplo -1px -1px, mueven la sombrea hacia la izquierda o hacia arriba.

+
+ +

Sombras múltiples

+ +

Puedes aplicar diversas sombras al mismo texto incluyendo múltiples valores de sombra separados por comas, por ejemplo:

+ +
text-shadow: -1px -1px 1px #aaa,
+             0px 4px 1px rgba(0,0,0,0.5),
+             4px 4px 5px rgba(0,0,0,0.7),
+             0px 0px 7px rgba(0,0,0,0.4);
+ +

Si aplicamos esto al elemento {{htmlelement("h1")}} de nuestro ejemplo Tommy The Cat, obtenemos esto:

+ + + +

{{ EmbedLiveSample('Sombras_múltiples', '100%', 220) }}

+ +
+

Nota: Puedes ver más ejemplos interesantes del uso de text-shadow en el artículo de Sitepoint Moonlighting with CSS text-shadow.

+
+ +

Diseño del texto

+ +

Una vez tratadas las propiedades básicas para los tipos de letra, echemos un vistazo a las propiedades que podemos usar para la disposición del texto.

+ +

Alineación del texto

+ +

La propiedad {{cssxref("text-align")}} se usa para controlar la forma en que el texto se alinea dentro de la caja que lo contiene. Los valores disponibles para esta propiedad son los siguientes, y funcionan de la misma forma que en una aplicación de procesamiento de texto:

+ + + +

Si aplicamos text-align: center; al elemento {{htmlelement("h1")}} de nuestro ejemplo, obtendremos esto:

+ + + +

{{ EmbedLiveSample('Alineación_del_texto', '100%', 220) }}

+ +

Interlineado

+ +

La propiedad {{cssxref("line-height")}} establece la altura entre cada línea de texto; esta propiedad admite la mayoría de las unidades y magnitudes, pero también puede tomar un valor sin unidades, que actúa como un multiplicador y generalmente se considera la mejor opción porque se multiplica la propiedad {{cssxref("font-size")}} para obtener la altura de la línea (line-height). El texto del cuerpo (body) generalmente se ve mejor y es más fácil de leer si hay más separación entre las líneas; la altura recomendada de la línea es entre 1.5-2 (a doble espacio). Por lo tanto, para configurar nuestras líneas de texto a 1.5 veces la altura de la fuente, deberías usar esto:

+ +
line-height: 1.5;
+ +

Aplicando esto a los elementos {{htmlelement("p")}} en nuestro ejemplo nos daría este resultado:

+ + + +

{{ EmbedLiveSample('Interlineado', '100%', 250) }}

+ +

Espacio entre letras y espacio entre palabras

+ +

Las propiedades {{cssxref("letter-spacing")}} y {{cssxref("word-spacing")}} te permiten establecer el espacio entre las letras y entre las palabras del texto. No los usarás a menudo, pero podría ser útil para obtener una apariencia determinada o para mejorar la legibilidad de un tipo de letra particularmente denso. Estas propiedades admiten la mayoría de las unidades y magnitudes.

+ +

Así, como ejemplo, podemos aplicar a la primera línea de los elementos {{htmlelement("p")}} de nuestro ejemplo lo siguiente:

+ +
p::first-line {
+  letter-spacing: 2px;
+  word-spacing: 4px;
+}
+ +

y obtendremos:

+ + + +

{{ EmbedLiveSample('Espacio_entre_letras_y_espacio_entre_palabras', '100%', 250) }}

+ +

Otras propiedades interesantes

+ +

Las propiedades anteriores nos dan una idea de cómo empezar a aplicar texto a una página web, pero hay muchas más propiedades que puedes usar. Nuestro objetivo aquí es solo exponer las más importantes. Cuando te hayas acostumbrado a usar las propiedades anteriores, también deberías explorar las siguientes:

+ +

Aplicación de estilos a tipos de letra:

+ + + +

Estilos de disposición de los textos

+ + + +

Propiedades abreviadas para los tipos de letra

+ +

Muchas propiedades relativas a los tipos de letra también pueden establecerse de forma abreviada con la propiedad {{cssxref("font")}}. Se escriben en el orden siguiente: {{cssxref("font-style")}}, {{cssxref("font-variant")}}, {{cssxref("font-weight")}}, {{cssxref("font-stretch")}}, {{cssxref("font-size")}}, {{cssxref("line-height")}}, and {{cssxref("font-family")}}.

+ +

De entre todas estas propiedades, solo font-size y font-family son obligatorias al usar la propiedad abreviada de font.

+ +

Se debe colocar una barra inclinada (slash) entre las propiedades {{cssxref("font-size")}} y {{cssxref("line-height")}}.

+ +

Un ejemplo completo se vería así:

+ +
font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif;
+ +

Aprendizaje activo: Jugar a aplicar estilos

+ +

En esta sección de aprendizaje activo no proponemos ningún ejercicio específico: Simplemente nos gustaría que juegues con algunas propiedades de diseño de tipo de letra / texto, ¡y a ver qué consigues! Puedes hacer esto con archivos HTML/CSS sin conexión, o puedes introducir tu código en el ejemplo editable en vivo a continuación.

+ +

Si te equivocas, puedes volver a empezar con el botón Reinicio.

+ + + +

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

+ +

Resumen

+ +

Esperamos que hayas disfrutado jugando con el texto en este artículo. El próximo artículo te enseñará todo lo que necesitas saber sobre la aplicación de estilos de lista en HTML.

+ +

{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/styling_text/index.html b/files/es/learn/css/styling_text/index.html new file mode 100644 index 0000000000..a87012ec5c --- /dev/null +++ b/files/es/learn/css/styling_text/index.html @@ -0,0 +1,57 @@ +--- +title: Estilo de texto +slug: Learn/CSS/Styling_text +tags: + - Beginner + - CSS + - CodingScripting + - Fonts + - Landing + - Links + - Module + - NeedsTranslation + - Text + - TopicStub + - font + - letter + - line + - lists + - shadow + - web fonts +translation_of: Learn/CSS/Styling_text +--- +
{{LearnSidebar}}
+ +

Con los conceptos básicos del lenguaje CSS cubiertos, el siguiente tema de CSS para concentrarse es estilizar texto — una de las cosas más comunes que hará con CSS. Aquí observamos los fundamentos para estilizar texto, incluyendo la configuración de fuente, negrita, cursiva, linea y espacios entre letras, sombras paralelas y otras funciones de texto. Completamos el módulo observando la aplicación de fuentes personalizadas en su página, y el diseño de listas y enlaces.

+ +

Requisitos previos

+ +

Antes de iniciar este módulo, ya debe estár familizarizado con HTML, como se explica en el módulo Introducción a HTML, y sentirse cómodo con los fundamentos de CSS, como se explica en Introducción a CSS.

+ +
+

Nota: Si está trabajando en una computadora/tableta/u otro dispositivo donde no tenga la capacidad de crear sus propios archivos, puede probar (la mayoría) de los ejemplos de código en un programa de codificación en línea como JSBin, CodePenThimble.

+
+ +

Guías

+ +

Este módulo contiene los siguientes artículos, los cuales le enseñarán todos los elementos esenciales detras del diseño de contenido de texto HTML.

+ +
+
Texto fundamental y estilo de fuente
+
En este artículo iremos a través de todos los aspectos básicos del estilo de texto/fuente en detalle, incluyendo configuraciones del peso de la fuente, la familia y el estilo, taquigrafía de fuente, alineación de texto y otros efectos, línea y espaciado de letras.
+
Estilos de listas
+
Las listas, en su mayor parte, se comportan como cualquier otro texto, pero hay algunas propiedades de CSS específicas para las listas que debe conocer, y algunas de las mejores prácticas para tener en cuenta. Este artículo explica todo.
+
Estilos de enlaces
+
Al diseñar enlaces, es importante comprender cómo hacer uso de pseudo-clases para diseñar estados de enlaces de manera efectiva, y cómo diseñar enlaces para su uso en características de interfaces variadas comunes tales como menús de navegación y pestañas. Veremos todos estos temas en este artículo.
+
Fuentes web
+
Aquí exploraremos las fuentes web en detalle — estas permiten descargar fuentes personalizadas junto con su página web, para permitir un estilo de texto más variado y personalizado.
+
+ +

Evaluaciones

+ +

Las siguientes evaluaciones pondrán a prueba su comprensión de las técnicas del diseño de texto cubiertas en las guías anteriores.

+ +
+
Escribiendo una página de inicio para la comunidad de la escuela
+
En esta evaluación, pondremos a prueba su comprensión del estilo del texto haciendo que redacte el texto de la página principal de la escuela comunitaria.
+
diff --git a/files/es/learn/css/styling_text/styling_links/index.html b/files/es/learn/css/styling_text/styling_links/index.html new file mode 100644 index 0000000000..b5180d51df --- /dev/null +++ b/files/es/learn/css/styling_text/styling_links/index.html @@ -0,0 +1,434 @@ +--- +title: Dar estilo a los enlaces +slug: Learn/CSS/Styling_text/Styling_links +translation_of: Learn/CSS/Styling_text/Styling_links +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}
+ +

A la hora de dar estilo a los enlaces, es importante comprender cómo utilizar las pseudoclases para diseñar los estados de un enlace de manera efectiva y cómo diseñar enlaces para su uso en diversas funciones de interfaz comunes, como menús y pestañas de navegación. Veremos todos estos temas en este artículo.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conceptos básicos de HTML (véase Introducción al HTML), conocimientos básicos de CSS (véase Introducción al CSS), nociones de aplicación de estilo con CSS a textos y tipos de letra.
Objetivo:Aprender a dar formato a los estados de un enlace y a usarlos de manera efectiva en algunas funciones de interfaz de usuario comunes, como los menús de navegación.
+ +

Echemos un vistazo a algunos enlaces

+ +

Analizamos cómo se implementan los enlaces en tu HTML de acuerdo con las buenas prácticas de Creación de hipervínculos. En este artículo desarrollaremos estos conocimientos y te mostraremos las buenas prácticas del diseño de enlaces.

+ +

Los estados de un enlace

+ +

Lo primero que hay que entender es el concepto de estados de un enlace (diferentes estados en los que pueden estar los enlaces, que pueden diseñarse usando diferentes pseudoclases):

+ + + +

Estilos predeterminados

+ +

El ejemplo siguiente ilustra cómo se comportará un enlace por defecto (el CSS simplemente amplía y centra el texto para que destaque más).

+ +
<p><a href="#">Un enlace simple</a></p>
+
+ +
p {
+  font-size: 2rem;
+  text-align: center;
+}
+ +

{{ EmbedLiveSample('Estilos_predeterminados', '100%', 120) }}

+ +
+

Nota: Todos los enlaces que hay en los ejemplos de esta página son simulados, encontrarás un símbolo # (almohadilla) en el lugar de una URL real. Esto es porque si incluyéramos enlaces reales, los ejemplos quedarían interrumpidos al hacer clic (daría error, o se cargaría una página en el ejemplo incrustado de la que no podrías volver atrás). # solo establece enlaces dentro de la misma página.

+
+ +

A medida que explores los estilos predeterminados, observarás algunas cosas:

+ + + +

Curiosamente, estos estilos predeterminados son casi los mismos que se utilizaban al inicio de los navegadores en la década de 1990. Esto se debe a que los usuarios conocen y esperan que sea de esta forma. Podría confundir a mucha gente que los enlaces se mostrasen de manera diferente. Esto no quiere decir que no puedas cambiar el formato de los enlaces, solo que no deberías alejarte mucho de la conducta esperada. Al menos deberías:

+ + + +

Los estilos por defecto se pueden desactivar/cambiar usando las propiedades CSS siguientes:

+ + + +
+

Nota: No estás limitado a las propiedades anteriores para diseñar tus enlaces; tienes libertad para usar cualquier propiedad que te guste. ¡Solo trata de que no resulte descabellado!

+
+ +

Dar formato a algunos enlaces

+ +

Ahora que hemos visto los estados predeterminados, veamos un conjunto típico de estilos de enlace.

+ +

Para empezar, escribiremos nuestro conjunto de reglas vacío:

+ +
a {
+
+}
+
+
+a:link {
+
+}
+
+a:visited {
+
+}
+
+a:focus {
+
+}
+
+a:hover {
+
+}
+
+a:active {
+
+}
+ +

Este orden es importante porque los estilos de enlace se construyen sobre los anteriores. Por ejemplo, los estilos de la primera regla se aplicarán a todas las reglas siguientes, y cuando activas un enlace también pasas con el cursor por encima. Si los pones en un orden incorrecto, no funcionarán adecuadamente. Para recordar este orden, puedes intentar utilizar una fórmula nemotécnica como LoVe Fears HAte.

+ +

Ahora vamos a añadir algo más de información para darles formato:

+ +
body {
+  width: 300px;
+  margin: 0 auto;
+  font-size: 1.2rem;
+  font-family: sans-serif;
+}
+
+p {
+  line-height: 1.4;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  padding: 2px 1px 0;
+}
+
+a:link {
+  color: #265301;
+}
+
+a:visited {
+  color: #437A16;
+}
+
+a:focus {
+  border-bottom: 1px solid;
+  background: #BAE498;
+}
+
+a:hover {
+  border-bottom: 1px solid;
+  background: #CDFEAA;
+}
+
+a:active {
+  background: #265301;
+  color: #CDFEAA;
+}
+ +

También proporcionaremos algún ejemplo de HTML al que aplicar CSS:

+ +
<p>Dispones de varios navegadores, como <a href="#">Mozilla
+Firefox</a>, <a href="#">Google Chrome</a> y
+<a href="#">Microsoft Edge</a>.</p>
+ +

Poner los dos juntos nos da este resultado:

+ +

{{ EmbedLiveSample('Dar_formato_a_algunos_enlaces', '100%', 150) }}

+ +

¿Qué hemos hecho aquí? Sin duda tiene un aspecto diferente al estilo predeterminado, pero todavía ofrece una experiencia lo suficientemente familiar como para que los usuarios sepan de qué se trata:

+ + + +

Aprendizaje activo: proporciona estilo a tus enlaces

+ +

En esta sesión de aprendizaje activo, queremos que tomes nuestro conjunto de reglas vacías y añadas tus propias declaraciones para lograr unos enlaces geniales. Da rienda suelta a tu imaginación. Estamos seguros de que puedes crear algo genial y tan funcional como nuestro ejemplo anterior.

+ +

Si te equivocas, puedes volver a empezar pulsando el botón Reinicio. Si te quedas encallado, pulsa el botón Mostrar la solución para recuperar el ejemplo anterior.

+ + + +

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

+ +

Incluir iconos en los enlaces

+ +

Una práctica común es incluir iconos en los enlaces para proporcionar más de un indicador en cuanto a qué tipo de contenido apunta. Echemos un vistazo a un ejemplo muy simple que añade un icono a enlaces externos (enlaces que conducen a otros sitios web). Este icono suele parecerse a una pequeña flecha que sale de un cuadro; para este ejemplo, usaremos este fantástico ejemplo de icons8.com.

+ +

Echemos un vistazo a algunos elementos HTML y CSS que nos van a proporcionar el efecto que queremos. En primer lugar, algunos elementos HTML sencillos para dar estilo:

+ +
<p>Para obtener más información sobre el tiempo, visite nuestra <a href="http://#">página del tiempo</a>,
+mire la <a href="http://#">Wikipedia</a>, o cheque
+<a href="http://#">Extreme Science</a>.</p>
+ +

A continuación, el CSS:

+ +
body {
+  width: 300px;
+  margin: 0 auto;
+  font-family: sans-serif;
+}
+
+p {
+  line-height: 1.4;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  padding: 2px 1px 0;
+}
+
+a:link {
+  color: blue;
+}
+
+a:visited {
+  color: purple;
+}
+
+a:focus, a:hover {
+  border-bottom: 1px solid;
+}
+
+a:active {
+  color: red;
+}
+
+a[href*="http"] {
+  background: url('https://mdn.mozillademos.org/files/12982/external-link-52.png') no-repeat 100% 0;
+  background-size: 16px 16px;
+  padding-right: 19px;
+}
+ +

{{ EmbedLiveSample('Incluir_iconos_en_los_enlaces', '100%', 150) }}

+ +

¿Qué pasa aquí? Omitiremos la mayor parte del CSS, ya que es la misma información que has visto antes. Sin embargo, la última regla es interesante: insertamos una imagen de fondo personalizada en enlaces externos de una manera similar a como manejamos viñetas personalizadas en los elementos de lista en el último artículo. Esta vez, sin embargo, utilizamos la propiedad abreviada {{cssxref("background")}} en lugar de las propiedades individuales. Establecemos la ruta a la imagen que queremos insertar, especificamos el valor no-repeat para que solo se inserte una copia, y luego especificamos la posición como al 100% a la derecha del contenido de texto y a 0 píxeles del extremo superior.

+ +

También usamos {{cssxref("background-size")}} para especificar el tamaño de la imagen de fondo (es útil tener un icono más grande y luego cambiar su tamaño de esta manera, según sea necesario para fines de diseño web adaptativo). Sin embargo, esto solo funciona con Internet Explorer 9 y versiones posteriores, por lo que si trabajas con navegadores antiguos, tendrás que cambiar el tamaño de la imagen e insertarla tal como es.

+ +

Finalmente, establecemos un área de relleno a la derecha ({{cssxref ("padding-right")}}) para los enlaces, para crear un espacio en que aparezca la imagen de fondo, de modo que no se superponga con el texto.

+ +

Un último apunte: ¿cómo seleccionamos solo los enlaces externos? Bueno, si escribes tus enlaces HTML de forma adecuada, solo deberías usar URL absolutos para los enlaces externos. Para enlazar con otras partes del mismo sitio web, resulta más eficiente usar enlaces relativos. Por lo tanto, el texto «http» solo debe aparecer en los enlaces externos y es posible seleccionarlos con un selector de atributos: a[href*="http"] selecciona los elementos {{HTMLElement ( "a")}}, pero solo si tienen un atributo {{htmlattrxref("href","a")}} con un valor que contiene «http» en algún lugar de su contenido textual.

+ +

Eso es todo. Vuelve a la sección de aprendizaje activo anterior ¡y prueba esta nueva técnica!

+ +
+

Nota: No te preocupes si aún no estás familiarizado con los fondos y el diseño web adaptativo, lo explicaremos en otros artículos.

+
+ +

Dar aspecto de botón a un enlace

+ +

Las herramientas que has explorado hasta ahora en este artículo también se pueden usar de otras maneras. Por ejemplo, los estados como hover se pueden usar para diseñar muchos elementos diferentes, no solo enlaces. Es posible que desees diseñar un estado que señale el paso del cursor por encima de párrafos, elementos de lista u otras cosas.

+ +

Además, suele ser bastante común dar a los enlaces un aspecto y un comportamiento de botón en ciertas circunstancias: el menú de navegación de un sitio web generalmente está marcado como una lista que contiene enlaces, y es posible aplicarle estilo fácilmente para que se parezca a un conjunto de botones de control o pestañas que proporcionan al usuario acceso a otras partes del sitio web. Vamos a ver cómo.

+ +

En primer lugar, un poco de HTML:

+ +
<ul>
+  <li><a href="#">Inicio</a></li> <li><a href="#">Pizza</a></li> <li><a href = "#">Música</a> </li> <li><a href="#">Wombats</a></li> <li><a href="#">Finlandia</a></li>
+</ul>
+ +

Y ahora nuestro CSS:

+ +
body,html {
+  margin: 0;
+  font-family: sans-serif;
+}
+
+ul {
+  padding: 0;
+  width: 100%;
+}
+
+li {
+  display: inline;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  display: inline-block;
+  width: 19.5%;
+  margin-right: 0.625%;
+  text-align: center;
+  line-height: 3;
+  color: black;
+}
+
+li:last-child a {
+  margin-right: 0;
+}
+
+a:link, a:visited, a:focus {
+  background: yellow;
+}
+
+a:hover {
+  background: orange;
+}
+
+a:active {
+  background: red;
+  color: white;
+}
+ +

Esto nos da el resultado siguiente:

+ +

{{ EmbedLiveSample('Dar_aspecto_de_botón_a_un_enlace', '100%', 100) }}

+ +

Vamos a explicar qué pasa aquí, y nos vamos a centrar en los aspectos más interesantes:

+ + + +
+

Nota: Es posible que hayas observado que en el HTML se han colocado todos los elementos de lista en una misma línea; esto es porque los espacios/saltos de línea que se colocan entre elementos de bloque crean espacios en la página, igual como lo hacen los espacios entre las palabras, y estos espacios romperían nuestro diseño de menú de navegación horizontal. Así que hemos eliminado esos espacios. Puede encontrar más información sobre este problema (y sus soluciones) en Combatir los espacios entre elementos de bloque colocados en línea.

+
+ +

Resumen

+ +

Esperamos que este artículo te haya proporcionado todo lo que necesitas saber acerca de los enlaces... ¡por ahora! En el artículo final de nuestro módulo de aplicar estilo al texto detallaremos cómo usar tipos de letra personalizados para sitios web (o tipos de letra para web, como se les conoce comúnmente).

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/css/styling_text/styling_lists/index.html b/files/es/learn/css/styling_text/styling_lists/index.html new file mode 100644 index 0000000000..eeb395313b --- /dev/null +++ b/files/es/learn/css/styling_text/styling_lists/index.html @@ -0,0 +1,392 @@ +--- +title: Aplicación de estilo a listas +slug: Learn/CSS/Styling_text/Styling_lists +translation_of: Learn/CSS/Styling_text/Styling_lists +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}
+ +

Las listas se comportan como cualquier otro texto en su mayor parte, pero hay algunas propiedades CSS específicas de las listas que debes conocer y algunas prácticas recomendadas a tener en cuenta. Este artículo te lo explica.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conocimientos básicos de HTML (estudio introducción a HTML), nociones de cómo trabaja con CSS (estudio introducción a CSS), Conocimientos básicos de CSS para texto y tipos de letra.
Objetivo:Familiarizarse con las buenas prácticas y propiedades relacionadas con la aplicación de estilo a listas.
+ +

Un ejemplo sencillo de lista

+ +

Para empezar, veamos un ejemplo sencillo de una lista. A lo largo de este artículo veremos listas no ordenadas, listas ordenadas y listas de descripciones; todas tienen características de estilo similares, algunas que son particulares del tipo de lista. El ejemplo sin ningún estilo aplicado está disponible en Github (consulta también el código fuente.)

+ +

El HTML para nuestro ejemplo de lista se ve así:

+ +
<h2>Shopping (unordered) list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<ul>
+  <li>Humous</li>
+  <li>Pitta</li>
+  <li>Green salad</li>
+  <li>Halloumi</li>
+</ul>
+
+<h2>Recipe (ordered) list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<ol>
+  <li>Toast pitta, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pitta with salad, humous, and fried halloumi.</li>
+</ol>
+
+<h2>Ingredient description list</h2>
+
+<p>Paragraph for reference, paragraph for reference, paragraph for reference,
+paragraph for reference, paragraph for reference, paragraph for reference.</p>
+
+<dl>
+  <dt>Humous</dt>
+  <dd>A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients.</dd>
+  <dt>Pitta</dt>
+  <dd>A soft, slightly leavened flatbread.</dd>
+  <dt>Halloumi</dt>
+  <dd>A semi-hard, unripened, brined cheese with a higher-than-usual melting point, usually made from goat/sheep milk.</dd>
+  <dt>Green salad</dt>
+  <dd>That green healthy stuff that many of us just use to garnish kebabs.</dd>
+</dl>
+ +

Si accedes al ejemplo en vivo e investigas los elementos de la lista usando las herramientas de desarrollador del navegador, observarás un par de valores de estilo predeterminados:

+ + + +

Manejar el espaciado de la lista

+ +

Al diseñar listas, es necesario ajustar el diseño para que mantengan los mismos espaciados verticales (a veces denominados ritmos verticales) que el resto de elementos circundantes, como párrafos e imágenes; y el mismo espaciado horizontal entre uno y otro (en Github puedes ver el ejemplo de diseño terminado, y también encontrar el código fuente.)

+ +

El CSS que se utiliza para aplicar estilo al texto y al espaciado de texto es el siguiente:

+ +
/* Estilos generales */
+
+html {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 10px;
+}
+
+h2 {
+  font-size: 2rem;
+}
+
+ul,ol,dl,p {
+  font-size: 1.5rem;
+}
+
+li, p {
+  line-height: 1.5;
+}
+
+/* Estilos para las listas de descripciones */
+
+
+dd, dt {
+  line-height: 1.5;
+}
+
+dt {
+  font-weight: bold;
+}
+
+dd {
+  margin-bottom: 1.5rem;
+}
+ + + +

Estilos específicos de las listas

+ +

Ahora que hemos analizado el espaciado general de las listas, exploremos algunas propiedades específicas de las listas. Para empezar, debes conocer tres propiedades que pueden establecerse en los elementos {{htmlelement("ul")}} o {{htmlelement("ol")}}:

+ + + +

El estilo de la viñeta

+ +

Como ya sabes, la propiedad {{cssxref("list-style-type")}} te permite establecer qué tipo de viñeta usar. En nuestro ejemplo, hemos establecido que se usen números romanos en mayúsculas para la lista ordenada, con:

+ +
ol {
+  list-style-type: upper-roman;
+}
+ +

Esto nos da el aspecto siguiente:

+ +

Una lista ordenada con las viñetas establecidas para aparecer fuera del texto del elemento de lista.

+ +

Puedes encontrar muchas más opciones si echas un vistazo a la página de referencia de {{cssxref("list-style-type")}}.

+ +

La posición de la viñeta

+ +

La propiedad {{cssxref("list-style-position")}} establece si las viñetas aparecen dentro de los elementos de la lista, o fuera de ellos antes del inicio de cada elemento. El valor por defecto es outside, que provoca que las viñetas se sitúen fuera de los elementos de lista, como se observa arriba.

+ +

Si estableces el valor en inside, las viñetas se ubican dentro de las líneas:

+ +
ol {
+  list-style-type: upper-roman;
+  list-style-position: inside;
+}
+ +

an ordered list with the bullet points set to appear inside the list item text.

+ +

Uso de una imagen personalizada como viñeta

+ +

La propiedad {{cssxref("list-style-image")}} te permite usar una imagen personalizada para tu viñeta. La sintaxis es muy simple:

+ +
ul {
+  list-style-image: url(star.svg);
+}
+ +

Sin embargo, esta propiedad es un poco limitada por lo que respecta al control de la posición, el tamaño, etc., de las viñetas. Es más conveniente usar la familia de propiedades {{cssxref("background")}}, de la cual aprenderás mucho más en el módulo Aplicar diseño a las cajas.

+ +

En nuestro ejemplo terminado, hemos aplicado estilo a la lista no ordenada de este modo (encima de lo que ya has visto arriba):

+ +
ul {
+  padding-left: 2rem;
+  list-style-type: none;
+}
+
+ul li {
+  padding-left: 2rem;
+  background-image: url(star.svg);
+  background-position: 0 0;
+  background-size: 1.6rem 1.6rem;
+  background-repeat: no-repeat;
+}
+ +

Aquí hemos hecho lo siguiente:

+ + + +

Esto nos da el resultado siguiente:

+ +

an unordered list with the bullet points set as little star images

+ +

Propiedad abreviada list-style

+ +

Es posible configurar las tres propiedades anteriores con una sola propiedad abreviada, {{cssxref("list-style")}}. Por ejemplo, observa el CSS siguiente:

+ +
ul {
+  list-style-type: square;
+  list-style-image: url(example.png);
+  list-style-position: inside;
+}
+ +

Podría reemplazarse por esto:

+ +
ul {
+  list-style: square url(example.png) inside;
+}
+ +

Los valores pueden escribirse en cualquier orden, y puedes usar uno, dos o los tres (los valores por defecto que se utilizan para las propiedades que no están incluidas son disc, none y outside). Si se especifican tanto type como image, el tipo se usa como una segunda opción en el caso de que la imagen no sea posible cargar la imagen por cualquier motivo.

+ +

Control de numeración de las listas

+ +

A veces puedes querer numerar las listas de manera diferente, por ejemplo, que empiece con un número que no sea el 1, o que cuente hacia atrás, o que cuente a saltos de más de una unidad. HTML y CSS tienen algunas herramientas para ayudarte con esto.

+ +

start

+ +

El atributo {{htmlattrxref("start","ol")}} te permite empezar la numeración de la lista en un número diferente de 1. Observa el ejemplo siguiente:

+ +
<ol start="4">
+  <li>Toast pitta, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pitta with salad, humous, and fried halloumi.</li>
+</ol>
+ +

Este código da el resultado siguiente:

+ +

{{ EmbedLiveSample('start', '100%', 150) }}

+ +

reversed

+ +

El atributo {{htmlattrxref("reversed","ol")}} empieza la lista contando hacia atrás, en lugar de hacia adelante. Observa el ejemplo siguiente:

+ +
<ol start="4" reversed>
+  <li>Toast pitta, leave to cool, then slice down the edge.</li>
+  <li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li>Wash and chop the salad.</li>
+  <li>Fill pitta with salad, humous, and fried halloumi.</li>
+</ol>
+ +

Da el resultado siguiente:

+ +

{{ EmbedLiveSample('reversed', '100%', 150) }}

+ +
+

Nota: Si en una lista inversa hay más elementos de lista que el valor que se ha establecido para el atributo start, la numeración continuará hasta cero y luego con valores negativos.

+
+ +

value

+ +

El atributo {{htmlattrxref("value","ol")}} te permite establecer para tus elementos de lista unos valores numéricos específicos. Observa el ejemplo siguiente:

+ +
<ol>
+  <li value="2">Toast pitta, leave to cool, then slice down the edge.</li>
+  <li value="4">Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
+  <li value="6">Wash and chop the salad.</li>
+  <li value="8">Fill pitta with salad, humous, and fried halloumi.</li>
+</ol>
+ +

Da el resultado siguiente:

+ +

{{ EmbedLiveSample('value', '100%', 150) }}

+ +
+

Nota: Incluso si utilizas una propiedad {{cssxref("list-style-type")}} sin números, vas a tener que usar los valores numéricos equivalentes para el atributo value.

+
+ +

Aprendizaje activo: aplicar estilo a una lista anidada

+ +

En esta sesión de aprendizaje activo, queremos que tomes lo que has aprendido arriba y pruebes a aplicar estilo a una lista anidada. Te hemos provisto con un HTML, y queremos que hagas lo siguiente:

+ +
    +
  1. Poner viñetas cuadradas en la lista no ordenada.
  2. +
  3. Establecer un interlineado de 1,5 con respecto al tamaño de la letra tanto para la lista ordenada como para la lista no ordenada.
  4. +
  5. Poner letras minúsculas en la lista ordenada.
  6. +
  7. Juega con el ejemplo, libremente y cuanto quieras, experimenta con los tipos de viñetas, los espacios, o cualquier otra cosa con que te encuentres.
  8. +
+ +

Si te equivocas, puedes volver a empezar con el botón Reinicio. Si te quedas encallado, pulsa el botón Mostrar la solución para ver una posible solución.

+ + + +

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

+ +

Véase también

+ +

Los contadores CSS proporcionan herramientas avanzadas para la personalización de las numeraciones y la aplicación de estilo a las listas, pero son bastante complejos. Te recomendamos echarles un vistazo si quieres ampliar tus conocimientos. Consulta:

+ + + +

Resumen

+ +

La aplicación de estilo a listas se domina con relativa facilidad una vez que conoces algunos principios básicos y propiedades específicas asociados. En el artículo siguiente vamos a continuar con las técnicas de aplicación de estilo a enlaces.

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}

+ +

En este módulo

+ + diff --git "a/files/es/learn/css/s\303\241bercomo/generated_content/index.html" "b/files/es/learn/css/s\303\241bercomo/generated_content/index.html" new file mode 100644 index 0000000000..605e87f9e2 --- /dev/null +++ "b/files/es/learn/css/s\303\241bercomo/generated_content/index.html" @@ -0,0 +1,178 @@ +--- +title: Usando CSS para generar contenido +slug: Learn/CSS/Sábercomo/Generated_content +tags: + - CSS + - Fundamentos + - Guía + - Principiante + - Web + - graficos +translation_of: Learn/CSS/Howto/Generated_content +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Color", "Color") }}Esta es la 9ª sección del tutorial CSS Getting Started; Describe algunas formas en las que puede utilizar CSS para agregar contenido cuando se muestra un documento. Modifica su hoja de estilo para agregar contenido de texto y una imagen.

+ +

Informacion: Contenido

+ +

Una de las ventajas importantes de CSS es que le ayuda a separar el estilo de un documento de su contenido. Sin embargo, hay situaciones en las que tiene sentido especificar cierto contenido como parte de la hoja de estilo, no como parte del documento.

+ +

El contenido especificado en una hoja de estilo puede consistir en texto o imágenes. Especifica el contenido de su hoja de estilos cuando el contenido está estrechamente vinculado a la estructura del documento.

+ +
+
+

Más detalles

+ +

Especificar contenido en una hoja de estilo puede causar complicaciones. Por ejemplo, es posible que tenga versiones de idioma diferentes de su documento que comparten una hoja de estilo. Si parte de la hoja de estilo tiene que ser traducida, significa que debe colocar las partes de la hoja de estilos en archivos separados y organizar para que se vincule con las versiones de idioma adecuado de su documento.

+ +

Estas complicaciones no surgen si el contenido especificado incluye símbolos o imágenes que se aplican en todos los idiomas y culturas.

+ +

El contenido especificado en una hoja de estilo no se convierte en parte del DOM.

+
+
+ +

Texto contenido

+ +

CSS puede insertar contenido de texto antes o después de un elemento. Para especificar esto, haga una regla y agregue {{cssxref (':: before')}} o {{cssxref (':: after')}} al selector. En la declaración, especifique la propiedad {{cssxref ('content')}} con el contenido de texto como su valor.

+ +
+
Ejemplo
+ +

HTML

+ +
Un texto donde necesito <span class="ref">alguna cosa</span>
+
+ +

CSS

+ +
.ref::before {
+  font-weight: negrita;
+  color: navy;
+  content: "Reference: ";
+}
+ +

Output

+ +

{{ EmbedLiveSample('Text_content', 600, 30) }}

+
+ +
+
Mas detalles
+ +

El conjunto de caracteres de una hoja de estilo es UTF-8 de forma predeterminada, pero se puede especificar en el vínculo o en la hoja de estilos o en otras formas. Para obtener más información, consulte 4. 4 Representación de hoja de estilo CSS en la especificación CSS.

+ +

Los caracteres individuales también se pueden especificar mediante un mecanismo de escape que utiliza la barra invertida como el carácter de escape. Por ejemplo, \ 265B es el símbolo del ajedrez para una reina negra ♛. Para obtener más información, consulte Referencia a caracteres no representados en una codificación de caracteres y también Caracteres y caso en la Especificación CSS.

+
+ +

Imagen contenido

+ +

Para agregar una imagen antes o después de un elemento, puede especificar la URL de un archivo de imagen en el valor de la propiedad {{cssxref ('content')}}.

+ +
+
Ejemplo
+ +

Esta regla añade un espacio y un icono después de cada enlace que tiene el glosario de clases:

+ +
a.glossary:after {content: " " url("../images/glossary-icon.gif");}
+
+
+ +

Para agregar una imagen como fondo de un elemento, especifique la URL de un archivo de imagen en el valor de la propiedad {{cssxref ('background')}}. Esta es una propiedad abreviada que especifica el color de fondo, la imagen, cómo se repite la imagen y algunos otros detalles.

+ +
+
Ejemplo
+ +

Esta regla establece el fondo de un elemento específico, utilizando una URL para especificar un archivo de imagen.

+ +

El selector especifica el id del elemento. El valor no-repeat hace que la imagen aparezca sólo una vez:

+ +
#sidebar-box {background: url("../images/sidebar-ground.png") no-repeat;}
+
+
+ +
+
Mas detalles
+ +

Para obtener información sobre las propiedades individuales que afectan a los fondos y sobre otras opciones al especificar imágenes de fondo, consulte {{Cssxref ('fondo')}}, página de referencia.

+
+ +

Acción: Añadir una imagen de fondo

+ +

Esta imagen es un cuadrado blanco con una línea azul en la parte inferior:

+ + + + + + + +
Image:Blue-rule.png
+ +
    +
  1. Descargue el archivo de imagen en el mismo directorio que su archivo CSS. (Por ejemplo, haga clic con el botón derecho del ratón para obtener un menú contextual y, a continuación, seleccione Guardar imagen como y especifique el directorio que está utilizando para este tutorial).
  2. +
  3. Edit your CSS file and add this rule to the body, setting a background image for the entire page.
  4. +
  5. +
    background: url("Blue-rule.png");
    +
    + +

    La repetición de valor es la predeterminada, por lo que no es necesario especificarla. La imagen se repite horizontal y verticalmente, dando una apariencia como papel de escribir forrado:

    + +
    +

    Image:Blue-rule-ground.png

    + +
    +
    +

    Cascading Style Sheets

    +
    + +
    +

    Cascading Style Sheets

    +
    +
    +
    +
  6. +
+ +
+
Reto
+ +

Descarga esta imagen:

+ + + + + + + +
Image:Yellow-pin.png
+ +

Agrega una nueva regla a tu hoja de estilos, luego, agrega la imagen al inicio de cada linea:

+ +
+

Image:Blue-rule-ground.png

+ +
+
image:Yellow-pin.png Cascading Style Sheets
+ +
image:Yellow-pin.png Cascading Style Sheets
+
+
+ +
+
Possible solution
+ +

Add this rule to your stylesheet:

+ +
p:before{
+  content: url("yellow-pin.png");
+}
+
+ +

 

+Hide solution
+Ver la solución a este reto.
+ +

Qué sigue?

+ +

{{ nextPage("/en-US/docs/Web/Guide/CSS/Getting_Started/Lists", "Lists") }}Una forma común en que las hojas de estilos agregan contenido es marcando los elementos en las listas. La siguiente sección describe cómo especificar estilos para una lista de elementos.

diff --git "a/files/es/learn/css/s\303\241bercomo/index.html" "b/files/es/learn/css/s\303\241bercomo/index.html" new file mode 100644 index 0000000000..ffff1653c0 --- /dev/null +++ "b/files/es/learn/css/s\303\241bercomo/index.html" @@ -0,0 +1,81 @@ +--- +title: Usa CSS para resolver problemas comunes +slug: Learn/CSS/Sábercomo +translation_of: Learn/CSS/Howto +--- +
{{LearnSidebar}}
+ +

Los siguientes enlaces apuntan a soluciones comunes a los problemas cotidianos que necesitará resolver con CSS.

+ +

Casos de uso común

+ +
+ + + +
+ +

Uncommon or advanced techniques

+ +

Beyond the basics, CSS is allows very advanced design techniques. These articles help you tackle the hardest use cases you may face.

+ +

General

+ + + +

Advanced effects

+ + + +

Layout

+ + diff --git a/files/es/learn/desarrollo_web_front-end/index.html b/files/es/learn/desarrollo_web_front-end/index.html new file mode 100644 index 0000000000..f58a9ad486 --- /dev/null +++ b/files/es/learn/desarrollo_web_front-end/index.html @@ -0,0 +1,201 @@ +--- +title: Desarrollo web Front-end +slug: Learn/Desarrollo_web_Front-end +tags: + - Aprender + - CSS + - De lado del cliente + - Estándar Web + - Estándares web + - Front-end + - HTML + - Herramientas + - JavaScript + - Novato + - Principiante +translation_of: Learn/Front-end_web_developer +--- +

{{learnsidebar}}

+ +

¡Bienvenido a la ruta de aprendizaje para desarrolladores de la interfaz de usuario web!

+ +

Aquí se te proporciona un curso estructurado que te enseñará todo lo que necesitas saber para convertirte en un desarrollador de la interfaz de usuario web. Simplemente trabaja en cada sección, aprendiendo nuevas habilidades (o mejorando las existentes) sobre la marcha. Cada sección incluye desafíos y ejercicios para evaluar tu comprensión antes de seguir adelante.

+ +

Temas tratados

+ +

Los temas tratados son:

+ + + +

Puedes trabajar en las secciones en orden, pero cada una también es autónoma. Por ejemplo, si ya conoces HTML, puedes pasar a la sección CSS.

+ +

Prerrequisitos

+ +

No necesitas conocimientos previos para empezar este curso. Todo lo que necesitas es una computadora que pueda ejecutar navegadores web modernos, una conexión a Internet y la voluntad de aprender.

+ +

Si no estás seguro de si el desarrollo de la interfaz de usuario web es para ti, y/o deseas una breve introducción antes de comenzar un curso más largo y completo, consulta una {{web.link("/es/docs/Learn/Getting_started_with_the_web", "Introducción a la Web")}}.

+ +

Cómo obtener ayuda

+ +

Hemos tratado de hacer que el desarrollo de la interfaz de usuario web sea lo más cómodo posible, pero probablemente todavía quedes encallado porque no entiendes algo o porque algún código simplemente no funciona.

+ +

No entres en pánico. Todos hemos encallado, sin importar que seamos desarrolladores web principiantes o profesionales. El artículo {{web.link("/es/docs/Learn/Learning_and_getting_help", "Aprender y obtener ayuda")}} te brinda una serie de consejos para buscar información y ayudarte a ti mismo. Si aún estás atascado, no dudes en publicar una pregunta en nuestro Foro de discusión.

+ +

Empecemos. ¡Diviértete!

+ +

El camino del aprendizaje

+ +

Primeros pasos

+ +

Tiempo para completar: 1.5 a 2 horas

+ +

Prerrequisitos

+ +

Nada excepto conocimientos básicos de informática.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

No hay evaluaciones en esta parte del curso. Pero asegúrate de no saltarla. Es importante prepararte para trabajar en la resolución de los ejercicios más adelante en el curso.

+ +

Guías

+ + + +

Semántica y estructura con HTML

+ +

Tiempo para completar: 35 a 50 horas

+ +

Prerrequisitos

+ +

Nada, excepto: conocimientos básicos de informática y un entorno de desarrollo web básico.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

Las evaluaciones de cada módulo están diseñadas para comprobar tu conocimiento del tema. Completar las evaluaciones confirma que estás listo para pasar al siguiente módulo.

+ +

Módulos

+ + + +

Estilo y diseño con CSS

+ +

Tiempo para completar: 90 a 120 horas

+ +

Prerrequisitos

+ +

Es recomendable que tengas conocimientos básicos de HTML antes de comenzar a aprender CSS. Primero deberías estudiar {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML", "Introducción a HTML")}} por lo menos.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

Las evaluaciones de cada módulo están diseñadas para comprobar tu conocimiento del tema. Completar las evaluaciones confirma que estás listo para pasar al siguiente módulo.

+ +

Módulos

+ + + +

Recursos adicionales

+ + + +

Interactividad con JavaScript

+ +

Tiempo para completar: 135 a 185 horas

+ +

Prerrequisitos

+ +

Es recomendable que tengas conocimientos básicos de HTML antes de comenzar a aprender JavaScript. Primero deberías estudiar {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML", "Introducción a HTML")}} por lo menos.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

Las evaluaciones de cada módulo están diseñadas para comprobar tu conocimiento del tema. Completar las evaluaciones confirma que estás listo para pasar al siguiente módulo.

+ +

Módulos

+ + + +

Formularios web — Trabajar con datos del usuario

+ +

Tiempo para completar: 40 a 50 horas

+ +

Prerrequisitos

+ +

Los formularios requieren conocimientos de HTML, CSS y JavaScript. Dada la complejidad de trabajar con formularios, es un tema dedicado.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

Las evaluaciones de cada módulo están diseñadas para comprobar tu conocimiento del tema. Completar las evaluaciones confirma que estás listo para pasar al siguiente módulo.

+ +

Módulos

+ + + +

Hacer que la web funcione para todos

+ +

Tiempo para completar: 60 a 75 horas

+ +

Prerrequisitos

+ +

Es una buena idea conocer HTML, CSS y JavaScript antes de trabajar en esta sección. Muchas de las técnicas y mejores prácticas se refieren a múltiples tecnologías.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

Las evaluaciones de cada módulo están diseñadas para comprobar tu conocimiento del tema. Completar las evaluaciones confirma que estás listo para pasar al siguiente módulo.

+ +

Módulos

+ + + +

Herramientas modernas

+ +

Tiempo para completar: 55 a 90 horas

+ +

Prerrequisitos

+ +

Es una buena idea conocer HTML, CSS y JavaScript antes de trabajar en esta sección, ya que las herramientas analizadas funcionan junto con muchas de estas tecnologías.

+ +

¿Cómo sabré que estoy listo para seguir adelante?

+ +

No hay artículos de evaluación específicos en este conjunto de módulos. Los tutoriales de casos de estudio al final del segundo y tercer módulo te preparan para comprender los conceptos básicos de las herramientas modernas.

+ +

Módulos

+ + diff --git a/files/es/learn/getting_started_with_the_web/css_basics/index.html b/files/es/learn/getting_started_with_the_web/css_basics/index.html new file mode 100644 index 0000000000..af79920af3 --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/css_basics/index.html @@ -0,0 +1,283 @@ +--- +title: CSS básico +slug: Learn/Getting_started_with_the_web/CSS_basics +tags: + - CSS + - Codificacion/Scripting + - Estilos/Styling + - Principiante + - Web + - aprende +translation_of: Learn/Getting_started_with_the_web/CSS_basics +--- +
{{LearnSideBar}}
+ +
{{PreviousMenuNext("Learn/Getting_started_with_the_web/HTML_basics", "Learn/Getting_started_with_the_web/JavaScript_basics","Learn/Getting_started_with_the_web")}}
+ +
+

CSS (Hojas de Estilo en Cascada) es el código que usas para dar estilo a tu página web. CSS Básico te lleva a través de lo que tú necesitas para empezar. Contestará a preguntas del tipo: ¿Cómo hago mi texto rojo o negro? ¿Cómo hago que mi contenido se muestre en tal y tal lugar de la pantalla? ¿Cómo decoro mi página web con imágenes de fondo y colores?

+
+ +

Entonces ¿qué es CSS, realmente?

+ +

Como HTML, CSS (Cascading Style Sheets) u Hojas de estilo en cascada en español, no es realmente un lenguaje de programación, tampoco es un lenguaje de marcado. Es un lenguaje de hojas de estilo, es decir, te permite aplicar estilos de manera selectiva a elementos en documentos HTML. Por ejemplo, para seleccionar todos los elementos de párrafo en una página HTML y volver el texto dentro de ellos de color rojo, has de escribir este CSS:

+ +
p {
+  color: red;
+}
+ +

Vas a probarlo: pega estas tres líneas de CSS en un nuevo archivo en tu editor de texto y guarda este archivo como style.css en tu directorio styles (estilos).

+ +

Pero aún debes aplicar el CSS a tu documento HTML, de otra manera el estilo CSS no cambiará cómo tu navegador muestra el documento HTML. (Si no has seguido nuestro proyecto, lee Manejo de archivos y HTML básico para averiguar qué necesitas hacer primero.)

+ +
    +
  1. Abre tu archivo index.html y pega la siguiente línea en algún lugar dentro del {{htmlelement("head")}}, es decir, entre las etiquetas <head> y </head>: + +
    <link href="styles/style.css" rel="stylesheet" type="text/css">
    +
  2. +
  3. Guarda el archivo index.html y cárgalo en tu navegador. Debes ver algo como esto:
  4. +
+ +

Un logo de Mozilla y algunos párrafos. El texto del párrafo ha sido estilizado en rojo por nuestro css.Si tu texto del párrafo ahora es rojo, ¡felicitaciones, ya has escrito tu primer CSS de forma exitosa!

+ +

Anatomía de una regla CSS

+ +

Observa el código CSS de arriba, un poco más a detalle:

+ +

Partes de una declaracion de css

+ +

La estructura completa es llamada regla predeterminada (pero a menudo «regla» para abreviar). Nota también los nombres de las partes individuales:

+ +
+
Selector
+
El elemento HTML en el que comienza la regla. Esta selecciona el(los) elemento(s) a dar estilo (en este caso, los elementos {{htmlelement("p")}} ). Para dar estilo a un elemento diferente, solo cambia el selector.
+
Declaración
+
Una sola regla como color: red; especifica a cuál de las propiedades del elemento quieres dar estilo.
+
Propiedades
+
Maneras en las cuales puedes dar estilo a un elemento HTML. (En este caso, color es una propiedad del elemento {{htmlelement("p")}} ). En CSS, seleccionas qué propiedad quieres afectar en tu regla.
+
Valor de la propiedad
+
A la derecha de la propiedad, después de los dos puntos (:), tienes el valor de la propiedad, para elegir una de las muchas posibles apariencias para una propiedad determinada (hay muchos valores para color además de red).
+
+ +

Nota las otras partes importantes de la sintaxis:

+ + + +

De este modo para modificar varios valores de propiedad a la vez, solo necesitas escribirlos separados por punto y coma (;), así:

+ +
p {
+  color: red;
+  width: 500px;
+  border: 1px solid black;
+}
+ +

Seleccionar varios elementos

+ +

También puedes seleccionar varios elementos y aplicar una sola regla a todos ellos. Incluye varios selectores separados por comas (,). Por ejemplo:

+ +
p,li,h1 {
+  color: red;
+}
+ +

Diferentes tipos de selectores

+ +

Existen muchos tipos diferentes de selectores. Antes, solo viste los selectores de elementos, los cuales seleccionan todos los elementos de un tipo dado en los documentos HTML. Sin embargo puedes hacer selecciones más específicas que esas. En seguida están algunos de los tipos de selectores más comunes:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre del selectorQué seleccionaEjemplo
Selector de elemento (llamado algunas veces selector de etiqueta o tipo)Todos los elementos HTML del tipo especificado.p
+ Selecciona <p>
Selector de identificación (ID)El elemento en la página con el ID especificado (en una página HTML dada, solo se permite un único elemento por ID).#mi-id
+ Selecciona <p id="mi-id"> y <a id="mi-id">
Selector de claseLos elementos en la página con la clase especificada (una clase puede aparecer varias veces en una página)..mi-clase
+ Selecciona <p class="mi-clase"> y <a class="mi-clase">
Selector de atributoLos elementos en una página con el atributo especificado.img[src]
+ Selecciona <img src="mimagen.png"> pero no <img>
Selector de pseudoclaseLos elementos especificados, pero solo cuando esté en el estado especificado, por ejemplo cuando el puntero esté sobre él.a:hover
+ Selecciona <a>, pero solo cuando el puntero esté sobre el enlace.
+ +

Existen muchos más selectores para explorar, y podrás encontrar una lista más detallada en la guía de Selectores.

+ +

Fuentes y texto

+ +

Ahora que has explorado lo básico de CSS, empieza por añadir información y algunas reglas más a tu archivo style.css para que tu ejemplo se vea bonito. Primero, haz que tus fuentes y texto luzcan un poco mejor.

+ +
    +
  1. Antes que nada, regresa y busca las fuentes de Google Fonts que guardaste en un lugar seguro. Agrega el elemento {{htmlelement("link")}}... en algún lugar del head de tu archivo index.html (de nuevo, en cualquier lugar entre las etiquetas {{htmlelement("head")}} y </head>). Debe verse algo así: + +
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans" rel="stylesheet" type="text/css">
    +
  2. +
  3. Luego, borra la regla existente en tu archivo style.css. Fue una buena prueba, pero el texto en rojo en realidad no se ve muy bien.
  4. +
  5. +

    Añade las siguientes líneas (que se muestran a continuación), sustituyendo la asignación de font-family por tu selección de font-family que obtuviste en ¿Cuál será la apariencia de tu sitio Web? La propiedad font-family se refiere a la(s) fuente(s) que deseas usar en tu texto. Esta regla define una fuente base global y un tamaño de fuente para usar en toda la página. Dado que {{htmlelement("html")}} es el elemento primario (o padre) de toda la página, todos los elementos contenidos dentro de él heredan las propiedades font-size y font-family):

    + +
    html {
    +  font-size: 10px; /* px quiere decir 'píxeles': el tamaño de la fuente base es ahora de 10 píxeles de altura */
    +  font-family: "Open Sans", sans-serif; /* Este debe ser el resto del resultado que obtuviste de Google fonts */
    +}
    + +
    +

    Nota: se ha añadido un comentario para explicar qué significa «px». Todo lo que está en un documento de CSS entre /* y */ es un comentario en CSS, el cual el navegador descarta cuando carga el código. Este es un espacio donde puedes escribir notas útiles sobre lo que estás haciendo.

    +
    +
  6. +
  7. Ahora escoge el tamaño de fuente para los elementos que contienen texto dentro del cuerpo del HTML ({{htmlelement("h1")}}, {{htmlelement("li")}}, y {{htmlelement("p")}}). También centra el texto del título, escoge un ancho de línea y espaciado entre letras en el contenido del texto para hacerlo un poco más legible: +
    h1 {
    +  font-size: 60px;
    +  text-align: center;
    +}
    +
    +p, li {
    +  font-size: 16px;
    +  line-height: 2;
    +  letter-spacing: 1px;
    +}
    +
  8. +
+ +

Puedes ajustar estos valores en px para lograr que tu diseño luzca como desees, pero por lo general tu diseño debe verse así:

+ +

Un logo de Mozilla y algunos párrafos. se ha establecido una fuente sans-serif, se han ajustado los tamaños de las fuentes, la altura de las líneas y el espaciado de las letras, y se ha centrado el encabezamiento de la página principal.

+ +

Cajas, cajas, todo se trata de cajas

+ +

Una cosa que notarás sobre la escritura de CSS es que trata mucho sobre cajas —ajustando su tamaño, color, posición, etc—. Puedes pensar en la mayoría de los elementos HTML de tu página como cajas apiladas una sobre la otra.

+ +

Una gran pila de cajas o cajones puestos uno encima del otro.

+ +

No es de extrañar que el diseño de CSS esté basado principalmente en el modelo de caja. Cada una de las cajas que ocupa espacio en tu página tiene propiedades como estas:

+ + + +

tres cajas puestas una dentro de otra. De fuera a dentro están etiquetadas con el margen, el borde y el relleno

+ +

En esta sección también se utiliza:

+ + + +

Bien, ¡continúa y agrega más código CSS a la página! Sigue añadiendo estas reglas nuevas al final de la página, y no temas experimentar cambiando los valores para ver cómo resulta.

+ +

Cambiar el color de la página

+ +
html {
+  background-color: #00539F;
+}
+ +

Esta regla asigna un color de fondo a la página entera. Puedes cambiar el código de color por cualquiera como el que elegiste usar en tu proyecto.

+ +

Dar estilo al cuerpo del documento

+ +
body {
+  width: 600px;
+  margin: 0 auto;
+  background-color: #FF9500;
+  padding: 0 20px 20px 20px;
+  border: 5px solid black;
+}
+ +

Ahora tienes varias declaraciones en el elemento body. Revisa una por una:

+ + + +

Posicionar y dar estilo al título principal de la página

+ +
h1 {
+  margin: 0;
+  padding: 20px 0;
+  color: #00539F;
+  text-shadow: 3px 3px 1px black;
+}
+ +

Puedes haber notado que hay un hueco horrible en la parte superior de body. Esto sucede porque los navegadores vienen con estilos por defecto, ¡incluso cuando aún no se ha aplicado ningún archivo CSS! Esto podría parecer una mala idea, pero se quiere que aun una página sin estilizar sea legible. Para deshacerte de este espacio elimina el estilo por defecto, agregando margin: 0;.

+ +

Enseguida, se ha puesto un relleno arriba y abajo del título de 20 píxeles, y se hizo que el color del texto sea el mismo que el color de fondo de html.

+ +

Una propiedad muy interesante que se ha usado aquí es text-shadow, que aplica una sombra al texto del elemento. Sus cuatro valores son como sigue:

+ + + +

Una vez más, trata de experimentar con diferentes valores para ver cómo resulta.

+ +

Centrar la imagen

+ +
img {
+  display: block;
+  margin: 0 auto;
+}
+ +

Finalmente, centra la imagen para hacer que luzca mejor. Puedes usar nuevamente el truco de margin: 0 auto que usaste antes para body, pero existen diferencias que requieren que hagas algo más para que el código CSS funcione.

+ +

El elemento {{htmlelement("body")}} es un elemento en nivel de bloque (block-level), lo que significa que tomará espacio en la página y que puede tener otros valores de espacio aplicables como margen. Las imágenes, por otra parte, son elementos inline, lo que quiere decir que no puedes aplicarles márgenes, debes dar a la imagen un comportamiento de block-level usando display: block;.

+ +
+

Nota: las instrucciones anteriores asumen que estás usando una imagen más pequeña que el ancho establecido en body (600 píxeles). Si tu imagen es más grande, desbordará el cuerpo, derramándose en el resto de la página. Para solucionar esto, puedes hacer lo siguiente: 1) reducir el ancho de la imagen usando un editor gráfico, o 2) usar CSS para dimensionar la imagen estableciendo la propiedad {{cssxref("width")}} en el elemento <img> con un valor menor.

+
+ +
+

Nota: no te preocupes si aún no entiendes display: block; y la diferencia entre un elemento de bloque y un elemento inline. Lo entenderás en tanto estudies CSS a profundidad. Puedes encontrar más en cuanto a los diferentes valores disponibles para display en la página de referencia de display.

+
+ +

Conclusión

+ +

Si has seguido las instrucciones de esta publicación, deberías terminar con una página que luce algo así (también puedes ver nuestra versión aquí):

+ +

El logo de Mozilla centrado con título y párrafos. Ahora se ve muy bien de estilo, con un fondo azul para toda la página y un fondo naranja para la franja de contenido principal centrada.

+ +

Si te atoraste, puedes comparar tu trabajo con el código del ejemplo finalizado en GitHub.

+ +

Aquí, solo has arañado la superficie de CSS. Si quieres encontrar más, puedes ir a la página de aprendizaje de CSS.

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/HTML_basics", "Learn/Getting_started_with_the_web/JavaScript_basics","Learn/Getting_started_with_the_web")}}

diff --git "a/files/es/learn/getting_started_with_the_web/c\303\263mo_funciona_la_web/index.html" "b/files/es/learn/getting_started_with_the_web/c\303\263mo_funciona_la_web/index.html" new file mode 100644 index 0000000000..546baf0309 --- /dev/null +++ "b/files/es/learn/getting_started_with_the_web/c\303\263mo_funciona_la_web/index.html" @@ -0,0 +1,100 @@ +--- +title: Cómo funciona la web +slug: Learn/Getting_started_with_the_web/Cómo_funciona_la_Web +tags: + - Cliente + - DNS + - HTTP + - IP + - Infraestructura + - Internet + - Principiante + - Protocolos + - Servidor + - TCP + - Web +translation_of: Learn/Getting_started_with_the_web/How_the_Web_works +--- +
{{LearnSidebar()}}
+ +
{{PreviousMenu("Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}}
+ +
+

Cómo funciona la web proporciona una vista simplificada de lo que sucede cuando ves una página web en un navegador web de tu computador o teléfono.

+
+ +

Esta teoría no es esencial para escribir código web a corto plazo, pero en poco tiempo empezarás a beneficiarte realmente al entender lo que está sucediendo en el fondo.

+ +

Los clientes y servidores

+ +

Las computadoras conectadas a la web se llaman clientes y servidores. Un diagrama simplificado de cómo interactúan se vería así:

+ +

+ + + +

Las otras partes de la caja de herramientas

+ +

El cliente y el servidor que describimos anteriormente, no cuentan toda la historia. Hay muchas otras partes involucradas y vamos a describirlas a continuación.

+ +

Por ahora, imaginemos que la web es un camino. En un extremo de la carretera, está el cliente, que es como tu casa. En el extremo opuesto del camino, está el servidor, que es una tienda en la que deseas comprar algo.

+ +

+ +

Además del cliente y el servidor, también tenemos que saludar a:

+ + + +

Entonces, ¿qué sucede exactamente?

+ +

Cuando escribes una dirección web en el navegador (usando nuestra analogía para ir a la tienda):

+ +
    +
  1. El navegador va al servidor DNS y encuentra la dirección real del servidor donde el sitio web vive (encontrar la dirección de la tienda).
  2. +
  3. El navegador envía un mensaje de petición HTTP al servidor, pidiéndole que envíe una copia de la página web para el cliente (ir a la tienda y hacer un pedido). Este mensaje y todos los datos enviados entre el cliente y el servidor, se envían a través de tu conexión a Internet usando TCP/IP.
  4. +
  5. Siempre que el servidor apruebe la solicitud del cliente, el servidor enviará al cliente un mensaje «200 OK», que significa, «¡por supuesto que puedes ver ese sitio web! Aquí está.», y comenzará a enviar los archivos de la página web al navegador como una serie de pequeños trozos llamados paquetes de datos (la tienda te entrega tus productos y los llevas de regreso a casa).
  6. +
  7. El navegador reúne los pequeños trozos, forma un sitio web completo y te lo muestra (llegas a casa con tus nuevas compras).
  8. +
+ +

Explicación de los DNS

+ +

Las direcciones webs reales no son las agradables y fácilmente recordables secuencias que tecleas en la barra de direcciones para encontrar tus sitios webs favoritos. En realidad, se trata de secuencias de números, algo como 63.245.217.105.

+ +

Lo anterior se llama dirección IP y representa un lugar único en la web. Sin embargo, no es muy fácil de recordar, ¿verdad? Por eso se inventaron los servidores de nombres de dominio. Estos son servidores especiales que hacen coincidir una dirección web tecleada desde tu navegador («mozilla.org», por ejemplo) con la dirección real del sitio web (IP).

+ +

Los sitios webs se pueden acceder directamente a través de sus direcciones IP. Intenta acceder a la página web de Mozilla escribiendo 63.245.217.105 en la barra de dirección de una nueva pestaña en tu navegador. Puedes encontrar la dirección IP de un sitio web escribiendo su dominio en una herramienta como IP Checker.

+ +

Un nombre de dominio es más que otra forma de una dirección IP

+ +

Explicación de los paquetes

+ +

Anteriormente hemos utilizado el término paquetes para describir el formato en que los datos se envían desde el servidor al cliente. ¿Qué significa esto? Básicamente, que los datos se envían a través de la web como miles de trozos pequeños, permitiendo que muchos usuarios pueden descargar la misma página web al mismo tiempo. Si los sitios web fueran enviados como grandes trozos, sólo un usuario podría descargarlos a la vez, lo que volvería a la web muy ineficiente y poco divertida.

+ +

Ver también

+ + + +

Crédito

+ +

Foto de la calle: Street Composing, por Kevin D.

+ +

{{PreviousMenu("Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}}

diff --git a/files/es/learn/getting_started_with_the_web/html_basics/index.html b/files/es/learn/getting_started_with_the_web/html_basics/index.html new file mode 100644 index 0000000000..e4e4f856a3 --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/html_basics/index.html @@ -0,0 +1,224 @@ +--- +title: 'HTML: básico' +slug: Learn/Getting_started_with_the_web/HTML_basics +tags: + - Aprendizaje + - HTML + - Principiante + - Web +translation_of: Learn/Getting_started_with_the_web/HTML_basics +--- +

{{LearnSideBar}}

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/Dealing_with_files", "Learn/Getting_started_with_the_web/CSS_basics","Learn/Getting_started_with_the_web")}}

+ +

El Lenguaje de Marcado de Hipertexto (HTML) es el código que se utiliza para estructurar y desplegar una página web y sus contenidos. Por ejemplo, sus contenidos podrían ser párrafos, una lista con viñetas, o imágenes y tablas de datos. Como lo sugiere el título, este artículo te dará una comprensión básica de HTML y cúal es su función.

+ +

Entonces, ¿qué es HTML en realidad?

+ +

HTML no es un lenguaje de programación; es un lenguaje de marcado que define la estructura de tu contenido. HTML consiste en una serie de elementos que usarás para encerrar diferentes partes del contenido para que se vean o comporten de una determinada manera. Las etiquetas de encierre pueden hacer de una palabra o una imagen un hipervínculo a otro sitio, se pueden cambiar palabras a cursiva, agrandar o achicar la letra, etc. Por ejemplo, toma la siguiente línea de contenido:

+ +
Mi gato es muy gruñon
+ +

Si quieres especificar que se trata de un párrafo, podrías encerrar el texto con la etiqueta de párrafo ({{htmlelement("p")}}):

+ +
<p>Mi gato es muy gruñon</p>
+ +

Anatomía de un elemento HTML

+ +

Explora este párrafo en mayor profundidad.

+ +

elementos de gato gruñon

+ +

Las partes principales del elemento son:

+ +
    +
  1. La etiqueta de apertura: consiste en el nombre del elemento (en este caso, p), encerrado por paréntesis angulares (< >) de apertura y cierre. Establece dónde comienza o empieza a tener efecto el elemento —en este caso, dónde es el comienzo del párrafo—.
  2. +
  3. La etiqueta de cierre: es igual que la etiqueta de apertura, excepto que incluye una barra de cierre (/) antes del nombre de la etiqueta. Establece dónde termina el elemento —en este caso dónde termina el párrafo—.
  4. +
  5. El contenido: este es el contenido del elemento, que en este caso es sólo texto.
  6. +
  7. El elemento: la etiqueta de apertura, más la etiqueta de cierre, más el contenido equivale al elemento.
  8. +
+ +

Los elementos pueden también tener atributos, que se ven así:

+ +

atributo html

+ +

Los atributos contienen información adicional acerca del elemento, la cual no quieres que aparezca en el contenido real del elemento. Aquí class es el nombre del atributo y editor-note el valor del atributo. En este caso, el atributo class permite darle al elemento un nombre identificativo, que se puede utilizar luego para apuntarle al elemento información de estilo y demás cosas.

+ +

Un atributo debe tener siempre:

+ +
    +
  1. Un espacio entre este y el nombre del elemento (o del atributo previo, si el elemento ya posee uno o más atributos).
  2. +
  3. El nombre del atributo, seguido por un signo de igual (=).
  4. +
  5. Comillas de apertura y de cierre, encerrando el valor del atributo.
  6. +
+ +

Los atributos siempre se incluyen en la etiqueta de apertura de un elemento, nunca en la de cierre.

+ +
+

Nota: el atributo con valores simples que no contengan espacios en blanco ASCII (o cualesquiera de los caracteres " ' ` = < >) pueden permanecer sin entrecomillar, pero se recomienda entrecomillar todos los valores de atributo, ya que esto hace que el código sea más consistente y comprensible.

+
+ +

Anidar elementos

+ +

Puedes también colocar elementos dentro de otros elementos —esto se llama anidamiento—. Si, por ejemplo, quieres resaltar una palabra del texto (en el ejemplo la palabra «muy»), podemos encerrarla en un elemento {{htmlelement("strong")}}, que significa que dicha palabra se debe enfatizar:

+ +
<p>Mi gato es <strong>muy</strong> gruñon.</p>
+ +

Debes asegurarte que los elementos estén correctamente anidados: en el ejemplo de abajo, creaste la etiqueta de apertura del elemento {{htmlelement("p")}} primero, luego la del elemento {{htmlelement("strong")}}, por lo tanto, debes cerrar esta etiqueta primero, y luego la de <p>. Esto es incorrecto:

+ +
<p>Mi gato es <strong>muy gruñon.</p></strong>
+ +

Los elementos deben abrirse y cerrarse ordenadamente, de forma tal que se encuentren claramente dentro o fuera el uno del otro. Si estos se encuentran solapados, el navegador web tratará de adivinar lo que intentas decirle, pero puede que obtengas resultados inesperados. Así que, ¡no lo hagas!

+ +

Elementos vacíos

+ +

Algunos elementos no poseen contenido, y son llamados elementos vacíos. Toma, por ejemplo, el elemento {{htmlelement("img")}} de nuestro HTML:

+ +
<img src="images/firefox-icon.png" alt="Mi imagen de prueba">
+ +

Posee dos atributos, pero no hay etiqueta de cierre </img> ni contenido encerrado. Esto es porque un elemento de imagen no encierra contenido al cual afectar. Su propósito es desplegar una imagen en la página HTML, en el lugar en que aparece.

+ +

Anatomía de un documento HTML

+ +

Hasta ahora has visto lo básico de elementos HTML individuales, pero estos no son muy útiles por sí solos. Ahora verás cómo los elementos individuales son combinados para formar una página HTML entera. Vuelve a visitar el código de tu ejemplo en index.html (que viste por primera vez en el artículo Manejo de archivos):

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi pagina de prueba</title>
+  </head>
+  <body>
+    <img src="images/firefox-icon.png" alt="Mi imagen de prueba">
+  </body>
+</html>
+ +

Tienes:

+ + + +

Imágenes

+ +

Presta atención nuevamente al elemento imagen {{htmlelement("img")}}:

+ +
<img src="images/firefox-icon.png" alt="Mi imagen de prueba">
+ +

Como ya se dijo antes, incrusta una imagen en la página, en la posición en que aparece. Lo logra a través del atributo src (source), el cual contiene el path (ruta o ubicación) de tu archivo de imagen.

+ +

También se incluye un atributo alt (alternative) el cual contiene un texto que debería describir la imagen, y que podría ser accedido por usuarios que no pueden ver la imagen, quizás porque:

+ +
    +
  1. Son ciegos o tienen deficiencias visuales. Los usuarios con impedimentos visuales usualmente utilizan herramientas llamadas Lectores de pantalla (Screen Readers), los cuales les leen el texto contenido en el atributo alt.
  2. +
  3. Se produjo algún error en el código que impide que la imagen sea cargada. Como ejemplo, modifica deliberadamente la ubicación dentro del atributo src para que este sea incorrecto. Si guardas y recargas la página, deberías ver algo así en lugar de la imagen:
  4. +
+ +

atributo html

+ +

La frase clave acerca del texto alt de arriba es «texto que debería describir la imagen». El texto alt debe proporcionarle al lector la suficiente información como para que este tenga una buena idea de qué muestra la imagen. Por lo que tu texto actual «Mi imagen de prueba» no es para nada bueno. Un texto mucho mejor para el logo de Firefox sería: «El logo de Firefox: un zorro en llamas rodeando la Tierra».

+ +

Prueba a dar con mejores textos alt para tu imagen.

+ +
+

Nota: Descubre más acerca de la accesibilidad en el módulo de aprendizaje sobre la accesibilidad.

+
+ +

Marcado de texto

+ +

Esta sección cubrirá algunos de los elementos HTML básicos que usarás para el marcado de texto.

+ +

Encabezados

+ +

Los elementos de encabezado permiten especificar que ciertas partes del contenido son encabezados, o subencabezados del contenido. De la misma forma que un libro tiene un título principal, y que a su vez puede tener títulos por cada capítulo individual, y subtítulos dentro de ellos, un documento HTML puede tenerlos también. HTML posee seis niveles de encabezados, {{htmlelement("h1")}}–{{htmlelement("h6")}}, aunque probablemente solo llegues a usar 3-4 como mucho:

+ +
<h1>Mi título principal</h1>
+<h2>Mi título de nivel superior</h2>
+<h3>Mi subtítulo</h3>
+<h4>Mi sub-subtítulo</h4>
+ +

Intenta ahora añadir un título apropiado para tu página HTML, antes de tu elemento {{htmlelement("img")}}.

+ +
+

Nota: verás que el encabezamiento de nivel 1 tiene un estilo implícito. No utilices elementos de encabezado para hacer el texto más grande o más oscuro, porque este elemento se utiliza por accesibilidad y otras razones como el posicionamiento en buscadores (Search Engine Optimization, SEO). Intenta crear una secuencia significativa de encabezados en tus páginas, sin saltarte niveles.

+
+ +

Párrafos

+ +

Como se explicó más arriba, los elementos {{htmlelement("p")}} se utilizan para encerrar párrafos de texto; los usarás frecuentemente para el marcado de contenido de texto regular:

+ +
<p>Este es un simple parrafo</p>
+ +

Agrega uno o algunos párrafos a tu texto de ejemplo (deberías tenerlo de cuando estudiaste ¿Cuál será la apariencia de tu sitio web?), colocados directamente debajo del elemento <img>.

+ +

Listas

+ +

Mucho del contenido web está dado por listas, así que HTML tiene elementos especiales para ellas. El marcado de listas se realiza siempre en al menos dos elementos. Los dos tipos de listas más comunes son las listas ordenadas y las desordenadas:

+ +
    +
  1. Las listas desordenadas son aquellas en las que el orden de los items no es relevante, como en una lista de compras. Estas son encerradas en un elemento {{htmlelement("ul")}} (unordered list).
  2. +
  3. Las listas ordenadas son aquellas en las que el orden sí es relevante, como en una receta. Estas son encerradas en un elemento {{htmlelement("ol")}} (ordered list).
  4. +
+ +

Cada elemento de la lista se coloca dentro de un elemento {{htmlelement("li")}} (list item).

+ +

Por ejemplo, si quieres transformar parte del siguiente párrafo en una lista:

+ +
<p>En Mozilla, somos una comunidad de tecnólogos, pensadores, y constructores que trabajan juntos... </p>
+ +

Podrías hacer lo siguiente:

+ +
<p>En Mozilla, somos una comunidad de</p>
+
+<ul>
+  <li>tecnólogos</li>
+  <li>pensadores</li>
+  <li>constructores</li>
+</ul>
+
+<p>trabajando juntos... </p>
+ +

Intenta agregar una lista ordenada o desordenada en tu página de ejemplo.

+ +

Vínculos

+ +

Los vínculos o enlaces son muy importantes —son los que hacen de la web, la web—. Para implementar un vínculo, necesitas usar un vínculo simple — {{htmlelement("a")}} — la a es la abreviatura de la palabra inglesa «anchor» («ancla»). Para convertir algún texto dentro de un párrafo en un vínculo, sigue estos pasos:

+ +
    +
  1. Elige algún texto. Nosotros elegimos «Manifesto Mozilla».
  2. +
  3. Encierra el texto en un elemento <a>, así: +
    <a>Manifesto Mozilla</a>
    +
  4. +
  5. Proporciónale al elemento <a> un atributo href, así: +
    <a href="">Manifesto Mozilla</a>
    +
  6. +
  7. Completa el valor de este atributo con la dirección web con la que quieras conectar al vínculo: +
    <a href="https://www.mozilla.org/es-AR/about/manifesto/">Manifesto Mozilla</a>
    +
  8. +
+ +

Podrías obtener resultados inesperados si al comienzo de la dirección web omites la parte https:// o http:// llamada protocolo. Así que luego del marcado del vínculo, haz clic en él para asegurarte que te dirige a la dirección deseada.

+ +
+

href podría parecer, en principio, una opción un tanto oscura para un nombre de atributo. Si tienes problemas para recordarla, recuerda que se refiere a hypertext reference (referencia de hipertexto).

+
+ +

Ahora agrega un vínculo a tu página, si es que aún no lo hiciste.

+ +

Conclusión

+ +

Si lograste seguir todas las instrucciones de este artículo, deberías terminar con una página que se vea así (también puedes verla aquí):
+
+ Una captura de pantalla de la página web que muestra el logo de Firefox, un encabezado que dice «mozilla es genial» y dos párrafos de texto de relleno.

+ +

Si te estancas en algún paso, puedes comparar tu trabajo con el código de ejemplo terminado en Github.

+ +

Aquí realmente solo has rasguñado la superficie de HTML. Para aprender más, ve a la página de Aprendizaje HTML.

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/Dealing_with_files", "Learn/Getting_started_with_the_web/CSS_basics","Learn/Getting_started_with_the_web")}}

diff --git a/files/es/learn/getting_started_with_the_web/index.html b/files/es/learn/getting_started_with_the_web/index.html new file mode 100644 index 0000000000..05cadcde6c --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/index.html @@ -0,0 +1,68 @@ +--- +title: Primeros pasos en la Web +slug: Learn/Getting_started_with_the_web +tags: + - CSS + - Diseño + - Guía + - HTML + - Index + - Novato + - Principiante + - edición + - editor + - 'l10n:priority' + - teoria + - Índice +translation_of: Learn/Getting_started_with_the_web +--- +
{{LearnSidebar}}
+ +
+

Introducción a la Web es una serie concisa que te presenta los aspectos prácticos del desarrollo web. Configurarás las herramientas que necesitas para construir una sencilla página web y publicar tu propio código.

+
+ +

La historia de tu primer sitio web

+ +

Es mucho trabajo crear un sitio web profesional, así que si eres nuevo en el desarrollo web, te animamos a que empieces poco a poco. No crearás otro Facebook de inmediato, pero no es difícil tener tu propio sitio web sencillo en línea, así que comenzaremos por ahí.

+ +

Al trabajar en orden a través de los artículos que se enumeran a continuación, pasarás de la nada a tener tu primera página web en línea. ¡Comencemos nuestro viaje!

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/Installing_basic_software","Instalación de software básico")}}

+ +

Cuando se trata de herramientas para crear un sitio web, hay mucho para elegir. Si recién estás comenzando, es posible que te sientas confundido por la variedad de editores de código, marcos de desarrollo y herramientas de prueba que existen. En {{web.link("/es/docs/Learn/Getting_started_with_the_web/Installing_basic_software", "Instalación de software básico")}}, te mostramos paso a paso cómo instalar solo el software que necesitas para comenzar un desarrollo web básico.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like","¿Cuál será la apariencia de tu sitio web?")}}

+ +

Antes de comenzar a escribir el código para tu sitio web, primero lo debes planificar. ¿Qué información estás mostrando?, ¿qué fuentes y colores estás usando?, en {{web.link("/es/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like", "¿cuál será la apariencia de tu sitio web?")}}, describimos un método simple que puedes seguir para planificar el contenido y modelado de tu sitio.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/Dealing_with_files","Manejo de archivos")}}

+ +

Un sitio web consta de muchos archivos: texto del contenido, código, hojas de estilo, contenido multimedia, etc. Cuando estás creando un sitio web, necesitas ensamblar estos archivos en una estructura sensata y asegurarte de que se puedan comunicar entre sí. {{web.link("/es/docs/Learn/Getting_started_with_the_web/Dealing_with_files", "Manejo de archivos")}} explica cómo configurar una estructura de archivos sensible para tu sitio web y qué problemas debes tener en cuenta.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/HTML_basics","Conceptos básicos de HTML")}}

+ +

El lenguaje de marcado de hipertexto (HTML) es el código que utilizas para estructurar tu contenido web y darle significado y propósito. Por ejemplo, ¿mi contenido es un conjunto de párrafos o una lista de viñetas?, ¿tengo imágenes insertadas en mi página?, ¿tengo una tabla de datos?; Sin abrumarte, {{web.link("/es/docs/Learn/Getting_started_with_the_web/HTML_basics", "conceptos básicos de HTML")}} proporciona suficiente información para familiarizarte con HTML.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/CSS_basics","Conceptos básicos de CSS")}}

+ +

Hojas de estilo en cascada (CSS) es el código que utilizas para aplicar estilo a tu sitio web. Por ejemplo, ¿desea que el texto sea negro o rojo?, ¿dónde se debe dibujar el contenido en la pantalla?, ¿qué imágenes de fondo y colores se deben utilizar para decorar tu sitio web?, {{web.link("/es/docs/Learn/Getting_started_with_the_web/CSS_basics", "Conceptos básicos de CSS")}} te indica lo que necesitas para empezar.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics","Conceptos básicos de JavaScript")}}

+ +

JavaScript es el lenguaje de programación que utilizas para agregar funciones interactivas a tu sitio web. Algunos ejemplos podrían ser juegos, cosas que suceden cuando se presionan botones o se ingresan datos en formularios, efectos de estilo dinámico, animación y mucho más. {{web.link("/es/docs/Learn/Getting_started_with_the_web/JavaScript_basics", "Conceptos básicos de JavaScript")}} te da una idea de lo que es posible con este interesante lenguaje y cómo empezar.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/Publishing_your_website","Publicar tu sitio web")}}

+ +

Una vez que hayas terminado de escribir el código y organizado los archivos que componen tu sitio web, lo debes poner todo en línea para que la gente lo pueda encontrar. {{web.link("/es/docs/Learn/Getting_started_with_the_web/Publishing_your_website", "Publica tu código de ejemplo")}} describe cómo publicar tu código de ejemplo en línea con el mínimo esfuerzo.

+ +

{{web.link("/es/docs/Learn/Getting_started_with_the_web/How_the_Web_works","Cómo funciona la web")}}

+ +

Cuando accedes a tu sitio web favorito, suceden muchas cosas complicadas en segundo plano que quizás no conozcas. {{web.link("/es/docs/Learn/Getting_started_with_the_web/How_the_Web_works", "Cómo funciona la web")}} describe lo que sucede cuando ves una página web en tu dispositivo favorito.

+ +

Ve también

+ + diff --git a/files/es/learn/getting_started_with_the_web/instalacion_de_software_basico/index.html b/files/es/learn/getting_started_with_the_web/instalacion_de_software_basico/index.html new file mode 100644 index 0000000000..84ffdcf666 --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/instalacion_de_software_basico/index.html @@ -0,0 +1,83 @@ +--- +title: Instalación de software básico +slug: Learn/Getting_started_with_the_web/Instalacion_de_software_basico +tags: + - Aprender + - Configuración + - Herramientas + - Navegadores + - Novato + - Principiantes + - aprende + - buscador + - editor de textos + - instalar + - 'l10n:priority' +translation_of: Learn/Getting_started_with_the_web/Installing_basic_software +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}
+ +
+

La Instalación de software básico, te muestra las herramientas que necesitas para hacer el desarrollo web simple, y la forma de instalarlas correctamente.

+
+ +

¿Qué herramientas usan los profesionales?

+ + + +

Ahora mismo: ¿qué herramientas necesitas realmente?

+ +

Esto parece una lista espeluznante pero, afortunadamente, puedes comenzar a trabajar en el desarrollo web sin saber nada de la mayoría de estas herramientas. En este artículo solo tendrás que configurar lo mínimo: un editor de texto y algunos navegadores web modernos.

+ +

Instalación de un editor de texto

+ +

Probablemente ya tengas un editor de texto básico instalado en tu computadora. De manera predeterminada Windows incluye el {{Interwiki("wikipedia", "Bloc de notas")}} y OS X viene con {{Interwiki("wikipedia", "TextEdit")}}. Las distros (versiones) de Linux varían: Ubuntu viene con {{Interwiki("wikipedia", "Gedit")}}; distribuciones basadas en KDE suelen traer Kate o Kwrite.

+ +

Para el desarrollo Web, probablemente hay cosas mejores que el Bloc de notas o TextEdit. Una recomendación puede ser empezar con Brackets, un editor gratuito que ofrece vistas previas en vivo y sugerencias de código.

+ +

Instalación de navegadores web modernos

+ +

Por ahora, solo tendrás que instalar un par de navegadores web de escritorio para poner a prueba tu código. Selecciona tu sistema operativo y pulsa los enlaces pertinentes para descargar los instaladores de tus navegadores preferidos:

+ + + +

Antes de continuar, deberías instalar al menos dos de estos navegadores y tenerlos disponibles para pruebas.

+ +
+

Nota: Internet Explorer no es compatible con algunas funciones web modernas y es posible que no puedas ejecutar tu proyecto. Por lo general, no necesitas preocuparte por hacer que tus proyectos web sean compatibles con él, ya que muy pocas personas todavía lo usan; ciertamente, no te preocupes demasiado por él mientras aprendes. En ocasiones, es posible que te encuentres con un proyecto que requiera soporte.

+
+ +

Instalación de un servidor web local

+ +

Algunos ejemplos necesitarás ejecutarlos a través de un servidor web para que funcionen exitosamente. Puedes encontrar cómo hacer esto en {{web.link("/es/docs/Learn/Common_questions/set_up_a_local_testing_server", "¿Cómo se configura un servidor de prueba local?")}}

+ +

{{NextMenu("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/getting_started_with_the_web/javascript_basics/index.html b/files/es/learn/getting_started_with_the_web/javascript_basics/index.html new file mode 100644 index 0000000000..78fa13eccb --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/javascript_basics/index.html @@ -0,0 +1,456 @@ +--- +title: Fundamentos de JavaScript +slug: Learn/Getting_started_with_the_web/JavaScript_basics +tags: + - Aprender + - CodingScripting + - JavaScript + - Novato + - Principiante + - Web + - 'l10n:priority' +translation_of: Learn/Getting_started_with_the_web/JavaScript_basics +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext( "Learn/Getting_started_with_the_web/CSS_basics","Learn/Getting_started_with_the_web/Publishing_your_website","Learn/Getting_started_with_the_web")}}
+ +
+

JavaScript es el lenguaje de programación que debes usar para añadir características interactivas a tu sitio web, (por ejemplo, juegos, eventos que ocurren cuando los botones son presionados o los datos son introducidos en los formularios, efectos de estilo dinámicos, animación, y mucho más). Este artículo te ayudará a comenzar con este lenguaje extraordinario y te dará una idea de qué es posible hacer con él.

+
+ +

¿Qué es JavaScript realmente?

+ +

{{Glossary("JavaScript")}} es un robusto lenguaje de programación que se puede aplicar a un documento {{Glossary("HTML")}} y usarse para crear interactividad dinámica en los sitios web. Fue inventado por Brendan Eich, cofundador del proyecto Mozilla, Mozilla Foundation y la Corporación Mozilla.

+ +

Puedes hacer casi cualquier cosa con JavaScript. Puedes empezar con pequeñas cosas como carruseles, galerías de imágenes, diseños fluctuantes, y respuestas a las pulsaciones de botones. Con más experiencia, serás capaz de crear juegos, animaciones 2D y gráficos 3D, aplicaciones integradas basadas en bases de datos ¡y mucho más!

+ +

JavaScript por sí solo es bastante compacto aunque muy flexible, y los desarrolladores han escrito gran cantidad de herramientas encima del núcleo del lenguaje JavaScript, desbloqueando una gran cantidad de funcionalidad adicional con un mínimo esfuerzo. Esto incluye:

+ + + +

Ya que se supone que este artículo es solo una introducción ligera a JavaScript, la intención no es confundirte en esta etapa hablando en detalle sobre cuál es la diferencia entre el núcleo del lenguaje JavaScript y las diferentes herramientas listadas arriba. Puedes aprender todo eso en detalle más tarde, en el Área de Aprendizaje en MDN, y en el resto de MDN.

+ +

Debajo se presentan algunos aspectos del núcleo del lenguaje y también jugarás con unas pocas características de la API del navegador. ¡Diviértete!

+ +

Ejemplo «¡Hola Mundo!»

+ +

La sección de arriba suena realmente emocionante, y debería serlo. JavaScript es una de las tecnologías web más emocionantes, y cuando comiences a ser bueno en su uso, tus sitios web entrarán en una nueva dimensión de energía y creatividad.

+ +

Sin embargo, sentirse cómodo con JavaScript es un poco más difícil que sentirse cómodo con HTML y CSS. Deberás comenzar poco a poco y continuar trabajando en pasos pequeños y consistentes. Para comenzar, mostraremos cómo añadir JavaScript básico a tu página, creando un «¡Hola Mundo!» de ejemplo (el estándar en los ejemplos básicos de programación).

+ +
+

Importante: si no has venido siguiendo el resto de nuestro curso, descarga este código de ejemplo y úsalo como punto de partida.

+
+ +
    +
  1. Primero, ve a tu sitio de pruebas y crea una carpeta llamada scripts. Luego, dentro de la nueva carpeta de scripts, crea un nuevo archivo llamado main.js y guárdalo.
  2. +
  3. A continuación, abre tu archivo index.html e introduce el siguiente código en una nueva línea, justo antes de la etiqueta de cierre </body>: +
    <script src="scripts/main.js"></script>
    +
  4. +
  5. Esto hace básicamente el mismo trabajo que el elemento {{htmlelement("link")}} para CSS: aplica el código JavaScript a la página, para que pueda actuar sobre el HTML (y CSS, o cualquier cosa en la página).
  6. +
  7. Ahora añade el siguiente código al archivo main.js: +
    const miTitulo = document.querySelector('h1');
    +miTitulo.textContent = '¡Hola mundo!';
    +
  8. +
  9. Finalmente, asegúrate de que has guardado los archivos HTML y JavaScript, y abre index.html en el navegador. Deberías ver algo así:
  10. +
+ +
+

Nota: la razón por la que has puesto el elemento {{htmlelement("script")}} casi al final del documento HTML es porque el navegador carga el HTML en el orden en que aparece en el archivo.

+ +

Si se cargara primero JavaScript y se supone que debe afectar al HTML que tiene debajo, podría no funcionar, ya que ha sido cargado antes que el HTML sobre el que se supone debe trabajar. Por lo tanto, colocar el JavaScript cerca del final de la página es normalmente la mejor estrategia. Para aprender más sobre enfoques alternativos, mira Estrategias de carga de scripts.

+
+ +

¿Qué ha ocurrido?

+ +

El texto del título ha sido cambiado por ¡Hola mundo! usando JavaScript. Hiciste esto primero usando la función {{domxref("Document.querySelector", "querySelector()")}} para obtener una referencia al título y almacenarla en una variable llamada miTitulo. Esto es muy similar a lo que hiciste con CSS usando selectores —quieres hacer algo con un elemento, así que tienes que seleccionarlo primero—.

+ +

Después de eso, estableciste el valor de la propiedad {{domxref("Node.textContent", "textContent")}} de la variable miTitulo (que representa el contenido del título) como ¡Hola mundo!

+ +
+

Nota: Las dos características que has utilizado en este ejercicio forman parte de la API del Modelo de Objeto de Documento (DOM), que tiene la capacidad de manipular documentos.

+
+ +

Curso intensivo de fundamentos del lenguaje

+ +

Ahora se explicarán algunas de las funciones básicas del lenguaje JavaScript para que puedas comprender mejor cómo funciona todo. Mejor aún, estas características son comunes para todos los lenguajes de programación. Si puedes entender esos fundamentos, deberías ser capaz de comenzar a programar en casi cualquier cosa.

+ +
+

Importante: en este artículo, trata de introducir las líneas de código de ejemplo en la consola de tu navegador para ver lo que sucede. Para más detalles sobre consolas JavaScript, mira Descubre las herramientas de desarrollo de los navegadores.

+
+ +

Variables

+ +

Las {{Glossary("Variable", "Variables")}} son contenedores en los que puedes almacenar valores. Primero debes declarar la variable con la palabra clave var (menos recomendado) o let, seguida del nombre que le quieras dar. Se recomienda más el uso de let que de var (más adelante se profundiza un poco sobre esto):

+ +
let nombreDeLaVariable;
+ +
+

Nota: todas las líneas en JS deben acabar en punto y coma (;) para indicar que es ahí donde termina la declaración. Si no los incluyes puedes obtener resultados inesperados. Sin embargo, algunas personas creen que es una buena práctica tener punto y coma al final de cada declaración. Hay otras reglas para cuando se debe y no se debe usar punto y coma. Para más detalles, vea Guía del punto y coma en JavaScript (en inglés).

+
+ +
+

Nota: puedes llamar a una variable con casi cualquier nombre, pero hay algunas restricciones (ver este artículo sobre las reglas existentes). Si no estás seguro, puedes comprobar el nombre de la variable para ver si es válido.

+
+ +
+

Nota: JavaScript distingue entre mayúsculas y minúsculas. miVariable es una variable distinta a mivariable. Si estás teniendo problemas en tu código, revisa las mayúsculas y minúsculas.

+
+ +
+

Nota: para más detalles sobre la diferencia entre var y let, vea Diferencia entre var y let.

+
+ +

Tras declarar una variable, puedes asignarle un valor:

+ +
nombreDeLaVariable = 'Bob';
+ +

Puedes hacer las dos cosas en la misma línea si lo necesitas:

+ +
let nombreDeLaVariable = 'Bob';
+ +

Puedes obtener el valor de la variable llamándola por su nombre:

+ +
nombreDeLaVariable;
+ +

Después de haberle dado un valor a la variable, puedes volver a cambiarlo:

+ +
let nombreDeLaVariable = 'Bob';
+nombreDeLaVariable = 'Steve';
+ +

Advierte que las variables tienen distintos tipos de datos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariableExplicaciónEjemplo
{{Glossary("String","String")}}Esto es una secuencia de texo conocida como cadena. Para indicar que la variable es una cadena, debes escribirlo entre comillas.let miVariable = 'Bob';
{{Glossary("Number")}} +

Esto es un número. Los números no tienen comillas.

+
let miVariable = 10;
{{Glossary("Boolean")}}Tienen valor verdadero/falso. true/false son palabras especiales en JS, y no necesitan comillas.let miVariable = true;
{{Glossary("Array")}}Una estructura que te permite almacenar varios valores en una sola referencia.let miVariable = [1,'Bob','Steve',10];
+ Llama a cada miembro del array así: miVariable[0], miVariable[1], etc.
{{Glossary("Object")}} +

Básicamente cualquier cosa. Todo en JavaScript es un objeto y puede ser almacenado en una variable. Mantén esto en mente mientras aprendes.

+
let miVariable = document.querySelector('h1');
+ Todos los ejemplos anteriores también.
+ +

Entonces, ¿para qué necesitamos las variables? Las variables son necesarias para hacer cualquier cosa interesante en programación. Si los valores no pudieran cambiar, entonces no podrías hacer nada dinámico, como personalizar un mensaje de bienvenida de un usuario que visita tu página, cambiar la imagen que se muestra en una galería de imágenes, etc.

+ +

Comentarios

+ +

Puedes escribir comentarios entre el código JavaScript, igual que puedes en CSS. El navegador ignora el texto marcado como comentario. En JavaScript, los comentarios de una sola línea se escriben así:

+ +
// Esto es un comentario
+ +

Pero también puedes escribir comentarios en más de una línea, igual que en CSS:

+ +
/*
+Esto es un comentario
+de varias líneas.
+*/
+ +

Operadores

+ +

Un {{Glossary("operator", "operador")}} es básicamente un símbolo matemático que puede actuar sobre dos valores (o variables) y producir un resultado. En la tabla de abajo aparecen los operadores más simples, con algunos ejemplos para probarlos en la consola del navegador.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorExplicaciónSímbolo(s)Ejemplo
Suma/concatenaSe usa para sumar dos números, o juntar dos cadenas en una.+6 + 9;
+ "Hola " + "mundo!";
Resta, multiplicación, divisiónEstos hacen lo que esperarías que hicieran en las matemáticas básicas.-, *, /9 - 3;
+ 8 * 2; // La multiplicación en JS es un asterisco
+ 9 / 3;
Operador de asignaciónLos has visto anteriormente: asigna un valor a una variable.=let miVariable = 'Bob';
identidad/igualdadComprueba si dos valores son iguales entre sí, y devuelve un valor de true/false (booleano).===let miVariable = 3;
+ miVariable === 4;
Negación, distinto (no igual)
+ En ocasiones utilizado con el operador de identidad, la negación es en JS el equivalente al operador lógico NOT — cambia true por false y viceversa.
!, !== +

La expresión básica es true, pero la comparación devuelve false porque lo hemos negado:

+ +

let miVariable = 3;
+ !miVariable === 3;

+ +

Aquí estamos comprobando "miVariable NO es igual a 3". Esto devuelve false, porque miVariable ES igual a 3.

+ +

let miVariable = 3;
+ miVariable !== 3;

+
+ +

Hay muchos operadores por explorar, pero con esto será suficiente por ahora. Mira Expresiones y operadores para ver la lista completa.

+ +
+

Nota: mezclar tipos de datos puede dar lugar a resultados extraños cuando se hacen cálculos, así que asegúrate de que relacionas tus variables correctamente y de que recibes los resultados que esperabas. Por ejemplo, teclea: "3" + "25" en tu consola. ¿Por qué no obtienes lo que esperabas? Porque las comillas convierten los números en "strings" (el término inglés para denominar cadenas de caracteres) y de este modo has acabado con los "strings" concatenados entre sí, y no con los números sumados. Si tecleas: 35 + 25, obtendrás el resultado correcto.

+
+ +

Condicionales

+ +

Las condicionales son estructuras de código que permiten comprobar si una expresión devuelve true o no, y después ejecuta un código diferente dependiendo del resultado. La forma de condicional más común es la llamada if... else. Entonces, por ejemplo:

+ +
let helado = 'chocolate';
+if (helado === 'chocolate') {
+  alert('¡Sí, amo el helado de chocolate!');
+} else {
+  alert('Awwww, pero mi favorito es el de chocolate...');
+}
+ +

La expresión dentro de if (... ) es el criterio — este usa al operador de identidad (descrito arriba) para comparar la variable helado con la cadena chocolate para ver si las dos son iguales. Si esta comparación devuelve true, el primer bloque de código se ejecuta. Si no, ese código se omite y se ejecuta el segundo bloque de código después de la declaración else.

+ +

Funciones

+ +

Las {{Glossary("Function", "funciones")}} son una manera de encapsular una funcionalidad que quieres reutilizar, de manera que puedes llamar esa función con un solo nombre, y no tendrás que escribir el código entero cada vez que la utilices. Ya has visto algunas funciones más arriba, por ejemplo:

+ +
    +
  1. +
    let nombreDeLaVariable = document.querySelector('h1');
    +
  2. +
  3. +
    alert('¡Hola!');
    +
  4. +
+ +

Estas funciones document.querySelector y alert están integradas en el navegador para poder utilizarlas en cualquier momento.

+ +

Si ves algo que parece un nombre de variable, pero tiene paréntesis —()— al final, probablemente es una función. Las funciones con frecuencia toman {{Glossary("Argument", "argumentos")}} —pedazos de datos que necesitan para hacer su trabajo—. Estos se colocan dentro de los paréntesis, y se separan con comas si hay más de uno.

+ +

Por ejemplo, la función alert() hace aparecer una ventana emergente dentro de la ventana del navegador, pero necesitas asignarle una cadena como argumento para decirle qué mensaje se debe escribir en la ventana emergente.

+ +

Las buenas noticias son que podemos definir nuestras propias funciones —en el siguiente ejemplo escribimos una función simple que toma dos números como argumentos y los multiplica entre sí—:

+ +
function multiplica(num1,num2) {
+  let resultado = num1 * num2;
+  return resultado;
+}
+ +

Trata de ejecutar la función anterior en la consola. Después trata de usar la nueva función algunas veces, p.ej:

+ +
multiplica(4, 7);
+multiplica(20, 20);
+multiplica(0.5, 3);
+
+ +
+

Nota: la sentencia return le dice al navegador que devuelva la variable resultado fuera de la función, para que esté disponible para su uso. Esto es necesario porque las variables definidas dentro de funciones, solo están disponibles dentro de esas funciones. Esto se conoce como «{{Glossary("Scope", "ámbito")}} (scope en inglés) de la variable». Lee más sobre ámbito o alcance de la variable.

+
+ +

Eventos

+ +

Para crear una interacción real en tu sitio web, debes usar eventos. Estos son unas estructuras de código que captan lo que sucede en el navegador, y permite que en respuesta a las acciones que suceden se ejecute un código. El ejemplo más obvio es un clic (click event), que se activa al hacer clic sobre algo. Para demostrar esto, prueba ingresando lo siguiente en tu consola, luego da clic sobre la página actual:

+ +
document.querySelector('html').onclick = function() {
+    alert('¡Ouch! ¡Deja de pincharme!');
+}
+
+ +

Hay muchas maneras de enlazar un evento a un elemento; aquí hemos seleccionado el elemento {{htmlelement("html")}} y le asignamos a su propiedad onclick una función anónima (función sin nombre) que contiene el código que se ejecutará cuando el evento suceda.

+ +

Nota que

+ +
document.querySelector('html').onclick = function(){};
+
+ +

es equivalente a

+ +
let miHTML = document.querySelector('html');
+miHTML.onclick = function(){};
+
+ +

es solo un modo más corto de escribirlo.

+ +

Sobrecargar tu sitio web de ejemplo

+ +

Ahora vas a repasar un poco lo básico de JavaScript. Añadirás un par de funcionalidades a tu sitio para demostrar lo que puedes hacer.

+ +

Añadir un cambiador de imagen

+ +

En esta sección añadirás otra imagen a tu sitio usando la DOM API y agregarás un poco de código para cambiar entre imágenes al hacer clic.

+ +
    +
  1. Primero que todo, busca una imagen que te guste para tu sitio. Asegúrate que sea del mismo tamaño que la primera, o lo más cerca posible.
  2. +
  3. Guarda tu imagen en tu carpeta images.
  4. +
  5. Renombra esta imagen «firefox2.png» (sin las comillas).
  6. +
  7. Ve a tu archivo main.js y agrega el siguiente JavaScript (si tu JavaScript de «Hola Mundo» está aún allí, bórralo). +
    let miImage = document.querySelector('img');
    +miImage.onclick = function () {
    +    let miSrc = miImage.getAttribute('src');
    +    if (miSrc === 'images/firefox-icon.png') {
    +      miImage.setAttribute('src','images/firefox2.png');
    +    } else {
    +      miImage.setAttribute('src', 'images/firefox-icon.png');
    +    }
    +}
    +
  8. +
  9. Guarda todos los archivos y carga index.html en tu navegador. Ahora cuando hagas clic en la imagen, ¡esta debe cambiar por otra!
  10. +
+ +

Esto fue lo que sucedió: se almacena una referencia a tu elemento {{htmlelement("img")}} en la variable miImage. Luego, haces que esta propiedad del manejador de evento onclick de la variable sea igual a una función sin nombre (una función «anónima»). Ahora, cada vez que se haga clic en la imagen:

+ +
    +
  1. El código recupera el valor del atributo src de la imagen.
  2. +
  3. El código usa una condicional para comprobar si el valor src es igual a la ruta de la imagen original: +
      +
    1. Si es así, el código cambia el valor de src a la ruta de la segunda imagen, forzando a que se cargue la otra imagen en el elemento {{htmlelement("img")}}.
    2. +
    3. Si no es así (significa que ya fue modificada), se cambiará el valor de src nuevamente a la ruta de la imagen original, regresando a como era en un principio.
    4. +
    +
  4. +
+ +

Añadir un mensaje de bienvenida personalizado

+ +

Ahora añadirás un poco más de código, para cambiar el título de la página o incluir un mensaje personalizado de bienvenida para cuando el usuario ingrese por primera vez. Este mensaje de bienvenida permanecerá luego de que el usuario abandone la página y estará disponible para cuando regrese. Lo guardarás usando Web Storage API. También se incluirá una opción para cambiar el usuario y por lo tanto también el mensaje de bienvenida en cualquier momento que se requiera.

+ +
    +
  1. En index.html, agrega el siguiente código antes del elemento {{htmlelement("script")}}: + +
    <button>Cambiar de usuario</button>
    +
  2. +
  3. En main.js, agrega el siguiente código al final del archivo, exactamente como está escrito. Esto toma referencia al nuevo botón que se agregó y al título y los almacena en variables: +
    let miBoton = document.querySelector('button');
    +let miTitulo = document.querySelector( 'h1');
    +
  4. +
  5. Ahora agrega la siguiente función para poner el saludo personalizado, lo que no causará nada aún, pero arreglarás esto en un momento: +
    function estableceNombreUsuario() {
    +    let miNombre = prompt('Por favor, ingresa tu nombre.');
    +    localStorage.setItem('nombre', miNombre);
    +    miTitulo.textContent = 'Mozilla es genial,' + miNombre;
    +}
    + La función estableceNombreUsuario() contiene una función prompt(), que crea un cuadro de diálogo como lo hace alert(); la diferencia es que prompt() pide al usuario un dato, y almacena este dato en una variable cuando el botón Aceptar del cuadro de diálogo es presionado. En este caso, pedirás al usuario que ingrese su nombre. Luego, llamarás la API localStorage, que nos permite almacenar datos en el navegador y recuperarlos luego. Usarás la función setItem() de localStorage, que crea y almacena un dato en el elemento llamado 'nombre', y coloca este valor en la variable miNombre que contiene el nombre que el usuario ingresó. Finalmente, establecerás el textContent del título a una cadena, más el nombre de usuario recientemente almacenado.
  6. +
  7. Luego, agregarás este bloque if ... else. Se podría llamar a esto el código de inicialización, como se ha establecido para cuando carga la app por primera vez: +
    if (!localStorage.getItem('nombre')) {
    +    estableceNombreUsuario();
    +}
    +else {
    +    let nombreAlmacenado = localStorage.getItem('nombre');
    +    miTitulo.textContent = 'Mozilla es genial,' + nombreAlmacenado;
    +}
    + La primera línea de este bloque usa el operador de negación (NO lógico representado por !) para comprobar si el elemento 'nombre' existe. Si no existe, la función estableceNombreUsuario() se iniciará para crearlo. Si ya existe (como por ejemplo cuando el usuario ya ingresó al sitio), se recupera el dato del nombre usando getItem() y se fija mediante textContent del título a la cadena, más el nombre del usuario, como hiciste dentro de estableceNombreUsuario().
  8. +
  9. Finalmente, agrega abajo el evento onclick que manipulará el botón, de modo que cuando sea pulsado se inicie la función estableceNombreUsuario(). Esto permitirá al usuario establecer un nuevo nombre cada vez que lo desee al pulsar el botón: +
    miBoton.onclick = function() {
    +    estableceNombreUsuario();
    +}
    +
  10. +
+ +

Ahora cuando visites tu sitio por primera vez, este te pedirá tu nombre y te dará un mensaje personalizado de bienvenida. Puedes cambiar cuantas veces quieras el nombre al presionar el botón. Y como un bonus añadido, ya que el nombre se almacena en el localStorage, este permanecerá después de que cierre el sitio, ¡manteniendo ahí el mensaje personalizado cuando abras el sitio la próxima vez!

+ +

¿Un nombre de usuario nulo?

+ +

Cuando ejecutes el ejemplo y obtengas el cuadro de diálogo que solicita que introduzcas tu nombre de usuario, intenta pulsar el botón Cancelar. Deberías terminar con un título que diga que Mozilla es genial, null. Esto sucede porque, cuando cancelas el mensaje, el valor se establece como null. Null (nulo) es un valor especial en JavaScript que se refiere a la ausencia de un valor.

+ +

Además, prueba a dar clic en Aceptar sin introducir un nombre. Deberías terminar con un título que diga que Mozilla es genial, por razones bastante obvias.

+ +

Para evitar estos problemas, podrías comprobar que el usuario no ha introducido un nombre en blanco. Actualiza tu función estableceNombreUsuario() a lo siguiente:

+ +
function estableceNombreUsuario() {
+  let miNombre = prompt('Introduzca su nombre.');
+  if(!miNombre) {
+    estableceNombreUsuario();
+  } else {
+    localStorage.setItem('nombre', miNombre);
+    miTitulo.innerHTML = 'Mozilla is genial, ' + miNombre;
+  }
+}
+ +

En el lenguaje humano, esto significa que si miNombre no tiene ningún valor, ejecute estableceNombreUsuario() de nuevo desde el principio. Si tiene un valor (si la afirmación anterior no es verdadera), entonces almacene el valor en localStorage y establézcalo como el texto del título.

+ +

Conclusión

+ +

Si has seguido las instrucciones en este artículo, tendrás una página que luzca como esta (también puede ver nuestra versión aquí):

+ +

+ +

Si tuviste problemas, siempre puedes comparar su trabajo con el código terminado del ejemplo en GitHub.

+ +

Aquí solo has rozado la superficie de JavaScript. Si has disfrutado aprendiendo y deseas avanzar más, visita la Guía de JavaScript.

+ +

Ve también

+ +
+
JavaScript
+
Sumérgete en JavaScript con mucho más detalle.
+
Aprende JavaScript
+
¡Este es un excelente material para los aspirantes a desarrolladores web! Aprende JavaScript en un entorno interactivo, con lecciones cortas y pruebas interactivas, guiadas por una evaluación automatizada. Las primeras 40 lecciones son gratis. El curso completo está disponible por un pequeño pago único (en inglés).
+
+ +

{{PreviousMenuNext( "Learn/Getting_started_with_the_web/CSS_basics","Learn/Getting_started_with_the_web/Publishing_your_website","Learn/Getting_started_with_the_web")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/getting_started_with_the_web/la_web_y_los_estandares_web/index.html b/files/es/learn/getting_started_with_the_web/la_web_y_los_estandares_web/index.html new file mode 100644 index 0000000000..daf6e77d18 --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/la_web_y_los_estandares_web/index.html @@ -0,0 +1,172 @@ +--- +title: La web y los estándares web +slug: Learn/Getting_started_with_the_web/La_web_y_los_estandares_web +tags: + - Estándares web + - Front-end + - Interfáz de Usuario + - Novato + - Principiante + - Web + - aprende +translation_of: Learn/Getting_started_with_the_web/The_web_and_web_standards +--- +

{{learnsidebar}}

+ +

Este artículo proporciona algunos antecedentes útiles sobre la Web — cómo surgió, qué son las tecnologías web estándar, cómo funcionan juntas, por qué "desarrollador web" es una gran carrera para elegir y qué tipos de mejores prácticas aprenderás a través de este curso.

+ +

Breve historia de la web

+ +

Mantendremos esto muy breve, ya que hay muchos artículos (más) detallados de la historia de la web, a los que enlazaremos más adelante (también intenta buscar "historia de la web" en tu motor de búsqueda favorito y ve lo que obtienes, si estás interesado en más detalles).

+ +

A fines de la década de 1960, las fuerzas armadas de EE. UU. desarrollaron una red de comunicación llamada {{Glossary("Arpanet")}}. Esta se puede considerar una precursora de la Web, ya que trabajó en la {{interwiki("wikipedia", "conmutación de paquetes")}} y presentó la primera implementación de la {{interwiki("wikipedia", "Familia de protocolos de internet")}} TCP/IP. Estas dos tecnologías forman la base de la infraestructura sobre la que se construye Internet.

+ +

En 1980, Tim Berners-Lee (a menudo denominado TimBL) escribió un programa de block de notas llamado ENQUIRE, que presentaba el concepto de enlaces entre diferentes nodos. ¿Te suena familiar?

+ +

Avanzó rápidamente hasta 1989, y TimBL escribió Gestión de la información: una propuesta e hipertexto en el CERN; estas dos publicaciones juntas proporcionaron los antecedentes de cómo funcionaría la web. Recibieron una buena cantidad de interés, suficiente para convencer a los jefes de TimBL de que le permitieran seguir adelante y creara un sistema de hipertexto global.

+ +

A finales de 1990, TimBL había creado todo lo necesario para ejecutar la primera versión de la web: {{web.link("/es/docs/Web/HTTP", "HTTP")}}, {{web.link("/es/docs/Web/HTML", "HTML")}}, el primer navegador web, que se llamaba {{interwiki("wikipedia", "WorldWideWeb")}}, un servidor HTTP y algunas páginas web para mirar.

+ +

En los años siguientes, la web explotó, se lanzaron varios navegadores, se instalaron miles de servidores web y se crearon millones de páginas web. Bien, este es un muy sencillo resumen de lo que sucedió, pero les prometí un breve resumen.

+ +

Un último dato importante para compartir es que en 1994, TimBL fundó el {{interwiki("wikipedia", "World Wide Web Consortium")}} (W3C), una organización que reúne a representantes de muchas empresas de tecnología diferentes para trabajar juntos en la creación de especificaciones de tecnología web. Después de eso, siguieron otras tecnologías como {{web.link("/es/docs/Web/CSS", "CSS")}} y {{web.link("/es/docs/Web/JavaScript", "JavaScript")}}, y la web comenzó a parecerse más a la web que conocemos hoy.

+ +

Estándares web

+ +

Los estándares web son las tecnologías que utilizamos para crear sitios web. Estos estándares existen como extensos documentos técnicos llamados especificaciones, que detallan exactamente cómo debería funcionar la tecnología. Estos documentos no son muy útiles para aprender a usar las tecnologías que describen (es por eso que tenemos sitios como MDN Web Docs), sino que están pensados ​​para que los utilicen los ingenieros de software para implementar esas tecnologías (generalmente en los navegadores web).

+ +

Por ejemplo, el lleno de vida Estándar HTML describe exactamente cómo se debe implementar HTML (todos los elementos HTML y sus APIs asociadas y otras tecnologías circundantes).

+ +

Los estándares web son creados por organismos de estándares — instituciones que invitan a grupos de personas de diferentes compañías de tecnología a unirse y acordar cómo deberían funcionar las tecnologías de la mejor manera posible para cumplir con todos sus casos de uso. El W3C es el organismo de estándares web más conocido, pero hay otros como WHATWG (que fueron responsables de la modernización del lenguaje HTML), ECMA (que publica el estándar para ECMAScript, en el que se basa JavaScript), Khronos (que publica tecnologías para gráficos 3D, como WebGL) y otras.

+ +

Estándares "abiertos"

+ +

Uno de los aspectos clave de los estándares web, que TimBL y el W3C acordaron desde el principio, es que la web (y las tecnologías web) deben ser libres tanto para contribuir como para usar, y no estar gravadas por patentes/licencias. Por lo tanto, cualquiera puede escribir el código para crear un sitio web de forma gratuita y cualquiera puede contribuir al proceso de creación de estándares, donde se escriben las especificaciones.

+ +

Debido a que las tecnologías web se crean abiertamente, en colaboración entre muchas empresas diferentes, significa que ninguna empresa las puede controlar, lo cual es algo realmente bueno. No querrías que una sola empresa decidiera repentinamente poner toda la web detrás de un muro de pago, o lanzar una nueva versión de HTML que todos tienen que comprar para continuar creando sitios web, o peor aún, simplemente decidiendo que ya no están interesados, y simplemente apagarlas.

+ +

Esto permite que la web siga siendo un recurso público de libre acceso.

+ +

No rompas la web

+ +

Otra frase que escucharás sobre los estándares web abiertos es "no rompas la web" — la idea es que cualquier tecnología web nueva que se introduzca debe ser compatible con versiones anteriores (es decir, los sitios web antiguos seguirán funcionando) y compatibles con versiones posteriores (las tecnologías futuras a su vez serán compatibles con las que tenemos actualmente). A medida que avances en el material de aprendizaje que se presenta aquí, comenzarás a aprender cómo se hace posible esto con un trabajo de diseño e implementación muy inteligente.

+ +

Ser desarrollador web es bueno

+ +

La industria web es un mercado muy atractivo para ingresar si estás buscando trabajo. Las cifras publicadas recientemente dicen que actualmente hay alrededor de 19 millones de desarrolladores web en el mundo, y esa cifra se establecerá en más del doble en la próxima década. Y al mismo tiempo, hay una escasez de habilidades en la industria, entonces, ¿qué mejor momento para aprender sobre desarrollo web?

+ +

Sin embargo, no todo es diversión y juegos — crear sitios web es una propuesta más complicada de lo que solía ser, y tendrás que dedicar algo de tiempo a estudiar todas las diferentes tecnologías que necesitas usar, todas las técnicas y las mejores prácticas que necesitas conocer y todos los patrones típicos que se te pedirá que implementes. Te tomará unos meses comenzar realmente a involucrarte en él, y luego deberás seguir aprendiendo para que tu conocimiento se mantenga actualizado con todas las nuevas herramientas y funciones que aparecen en la plataforma web, y seguir practicando y perfeccionando tu oficio.

+ +

Lo único constante es el cambio.

+ +

¿Esto suena difícil? No te preocupes: nuestro objetivo es brindarte todo lo que necesitas saber para comenzar, y las cosas serán más fáciles. Una vez que aceptes el cambio constante y la incertidumbre de la web, comenzarás a disfrutar. Como parte de la comunidad web, tendrás toda una red de contactos y material útil para ayudarte, y comenzarás a disfrutar de las posibilidades creativas que brinda.

+ +

Ahora eres un creativo digital. Disfruta de la experiencia y el potencial de ganarte la vida.

+ +

Descripción de las tecnologías web modernas

+ +

Hay una serie de tecnologías que debes aprender si deseas ser un desarrollador web front-end. En esta sección las describiremos brevemente. Para obtener una explicación más detallada de cómo funcionan juntas algunas de ellas, lee nuestro artículo {{web.link("/es/docs/Learn/Getting_started_with_the_web/How_the_Web_works", "Cómo funciona la web")}}.

+ + + +

Probablemente estés leyendo estas palabras dentro de un navegador web en este mismo momento (a menos que las hayas impreso o estés utilizando tecnología de asistencia, como un lector de pantalla para leerlas). Los navegadores web son los programas de software que la gente usa para consumir la web e incluyen Firefox, Chrome, Opera, Safari y Edge.

+ +

HTTP

+ +

El Protocolo de transferencia de hipertexto, o {{web.link("/es/docs/Web/HTTP/Basics_of_HTTP", "HTTP")}}, es un protocolo de mensajería que permite a los navegadores web comunicarse con los servidores web (donde se almacenan los sitios web). Una conversación típica es algo así como

+ +
"Hola servidor web. ¿Me puedes dar los archivos que necesito para renderizar bbc.co.uk"?
+
+"Seguro navegador web — aquí los tienes"
+
+[Descarga archivos y renderiza la página web]
+ +

La sintaxis real de los mensajes HTTP (llamados peticiones y respuestas) no es tan legible para los humanos, pero esto te da una idea básica.

+ +

HTML, CSS y JavaScript

+ +

{{web.link("/es/docs/Web/HTML", "HTML")}}, {{web.link("/es/docs/Web/CSS", "CSS")}} y {{web.link("/es/docs/Web/JavaScript", "JavaScript")}} son las tres tecnologías principales que utilizarás para crear un sitio web:

+ + + +

Herramientas

+ +

Una vez que hayas aprendido las tecnologías "sin procesar" que se pueden usar para crear páginas web (como HTML, CSS y JavaScript), pronto comenzarás a encontrar varias herramientas que puedes usar para hacer tu trabajo más fácil y/o más eficiente. Algunos ejemplos incluyen:

+ + + +

Marcos de desarrollo y lenguajes de lado del servidor

+ +

HTML, CSS y JavaScript son lenguajes de la interfaz del usuario ("front-end" o del lado del cliente), lo cual significa que los ejecuta el navegador para producir la interfaz del sitio web que los usuarios pueden utilizar.

+ +

Hay otra clase de lenguajes llamados lenguajes de la interfaz de admiración ("back-end" o de lado del servidor), lo cual significa que se ejecutan en el servidor antes de que el resultado se envíe al navegador para que se muestre. Un uso típico de un lenguaje de lado del servidor es obtener algunos datos de una base de datos y generar algo de HTML para contener los datos, antes de enviar el HTML al navegador para mostrárselo al usuario.

+ +

Los lenguajes de lado del servidor de ejemplo incluyen ASP.NET, Python, PHP y NodeJS.

+ +

Mejores prácticas web

+ +

Hemos hablado brevemente sobre las tecnologías que utilizarás para crear sitios web. Ahora analicemos las mejores prácticas que debes emplear para asegurarte de que estás utilizando esas tecnologías de la mejor manera posible.

+ +

Al hacer desarrollo web, la principal causa de incertidumbre proviene del hecho de que no sabes qué combinación de tecnologías utilizará cada usuario para ver tu sitio web:

+ + + +

Debido a que no sabes exactamente qué usarán tus usuarios, debes diseñar a la defensiva — hacer que tu sitio web sea lo más flexible posible, de modo que todos los usuarios anteriores puedan hacer uso de él, incluso si no todos obtienen la misma experiencia. En resumen, estamos tratando de hacer que la web funcione para todos, tanto como sea posible.

+ +

Encontrarás los siguientes conceptos en algún momento de tus estudios.

+ + + +

Ve también

+ + diff --git a/files/es/learn/getting_started_with_the_web/manejando_los_archivos/index.html b/files/es/learn/getting_started_with_the_web/manejando_los_archivos/index.html new file mode 100644 index 0000000000..0c7f8c4121 --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/manejando_los_archivos/index.html @@ -0,0 +1,120 @@ +--- +title: Manejo de archivos +slug: Learn/Getting_started_with_the_web/Manejando_los_archivos +tags: + - Archivos + - Guía + - HTML + - Novato + - Principiante + - Scripting + - Sitios Web + - 'l10n:priority' + - teorias +translation_of: Learn/Getting_started_with_the_web/Dealing_with_files +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web/HTML_basics", "Learn/Getting_started_with_the_web")}}
+ +
+

Un sitio web consta de muchos archivos: texto del contenido, código, hojas de estilo, contenido multimedia, etc. Cuando estás creando un sitio web, necesitas ensamblar estos archivos en una estructura sensible en tu computadora local, asegurarte de que puedan comunicarse entre sí y hacer que todo su contenido se vea bien antes de que eventualmente {{web.link("/es/Learn/Getting_started_with_the_web/Publishing_your_website", "los cargues en un servidor")}}. El manejo de archivos analiza algunos problemas que debes tener en cuenta, para que puedas configurar una estructura de archivos adecuada para tu sitio web.

+
+ +

¿Dónde debería estar tu sitio web en tu computadora?

+ +

Cuando estés trabajando en un sitio web localmente en tu computadora, debes mantener todos los archivos relacionados en un solo directorio que refleje la estructura de archivos del sitio web publicado en el servidor. Este directorio se puede ubicar en cualquier lugar que desees, pero debes colocarlo en algún lugar donde lo puedas encontrar fácilmente, tal vez en tu escritorio, en tu directorio de inicio o en la raíz de tu disco duro.

+ +
    +
  1. Elige un lugar para almacenar los proyectos de tus sitios web. Dentro del lugar elegido, crea un nuevo directorio llamado proyectosweb (o algo similar). Aquí es donde vivirán todos los proyectos de tus sitios web.
  2. +
  3. Dentro de este primer directorio, crea otro directorio para almacenar tu primer sitio web. Llámalo pruebasitio (o algo más imaginativo).
  4. +
+ +

Una acotación sobre la envoltura y el espaciado

+ +

Notarás que a lo largo de este artículo, te pedimos que nombres los directorios y archivos completamente en minúsculas sin espacios. Esto es porque:

+ +
    +
  1. Muchas computadoras, particularmente los servidores web, distinguen entre mayúsculas y minúsculas. Entonces, por ejemplo, si colocas una imagen en tu sitio web en pruebasitio/MiImagen.jpg y luego, en un archivo diferente intentas invocar la imagen como pruebasitio/miimagen.jpg, puede que no funcione.
  2. +
  3. Los navegadores, servidores web y lenguajes de programación no manejan los espacios de manera consistente. Por ejemplo, si usas espacios en tu nombre de archivo, algunos sistemas pueden tratar el nombre de archivo como dos nombres de archivo. Algunos servidores reemplazarán las áreas en tus nombres de archivo con "%20" (el código de caracteres para espacios en URI), lo cual provocará que todos tus enlaces se rompan. Es mejor separar las palabras con guiones, en lugar de guiones bajos: mi-archivo.html vs. mi_archivo.html.
  4. +
+ +

La respuesta corta es que debes usar un guión para los nombres de tus archivos. El motor de búsqueda de Google trata un guión como un separador de palabras, pero no considera un guión bajo de esa manera. Por estos motivos, es mejor adquirir el hábito de escribir los nombres de los directorios y archivos en minúsculas, sin espacios y con palabras separadas por guiones, al menos hasta que sepas lo que estás haciendo. De esa manera, tropezarás con menos problemas en el futuro.

+ +

¿Qué estructura debe tener tu sitio web?

+ +

A continuación, veamos qué estructura debería tener tu sitio de prueba. Las cosas más comunes que tendrás en cualquier proyecto de sitio web que crees son un archivo de índice HTML y directorios para contener imágenes, archivos de estilo y archivos de script. Crea estos ahora:

+ +
    +
  1. index.html: Este archivo generalmente tendrá el contenido de tu página de inicio, es decir, el texto y las imágenes que las personas ven cuando visitan tu sitio por primera vez. Usando tu editor de texto, crea un nuevo archivo llamado index.html y guárdalo dentro de tu directorio pruebasitio.
  2. +
  3. Directorio images: Este directorio contendrá todas las imágenes que utilices en tu sitio. Crea un directorio llamado images, dentro de tu directorio pruebasitio.
  4. +
  5. Directorio styles: Este directorio contendrá el código CSS que se utiliza para aplicar estilo al contenido (por ejemplo, configurar el texto y los colores de fondo). Crea un directorio llamado styles, dentro de tu directorio pruebasitio.
  6. +
  7. Directorio scripts: Este directorio contendrá todo el código JavaScript utilizado para agregar funcionalidad interactiva a tu sitio (por ejemplo, botones que cargan datos cuando se hace clic en ellos). Crea un directorio llamado scripts, dentro de tu directorio pruebasitio.
  8. +
+ +
+

Nota: En las computadoras con Windows, es posible que tengas problemas para ver los nombres de los archivos, porque de manera predeterminada, Windows tiene activada una opción llamada Ocultar extensiones para tipos de archivos conocidos. Generalmente, la puedes desactivar yendo al Explorador de Windows, seleccionando la opción Opciones de directorio..., desmarcando la casilla de verificación Ocultar extensiones para tipos de archivo conocidos y luego haciendo clic en Aceptar. Para obtener información más específica sobre tu versión de Windows, puedes buscar en la web.

+
+ +

Rutas de archivo

+ +

Para que los archivos se comuniquen entre sí, debes proporcionar una ruta de archivo entre ellos, básicamente una ruta, para que un archivo sepa dónde está otro. Para demostrarlo, insertaremos un poco de HTML en nuestro archivo index.html y haremos que muestre la imagen que elegiste en el artículo {{web.link("/es/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like#Imágenes", "¿Cómo se verá tu sitio web?")}}

+ +
    +
  1. Copia la imagen que elegiste anteriormente en tu directorio images.
  2. +
  3. Abre tu archivo index.html e inserta el siguiente código en el archivo exactamente como se muestra. Por ahora, no te preocupes por lo que significa todo esto; veremos las estructuras con más detalle más adelante en la serie. +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +    <meta charset="utf-8">
    +    <title>Mi página de prueba</title>
    +  </head>
    +  <body>
    +    <img src="" alt="Mi imagen de prueba">
    +  </body>
    +</html>
    +
  4. +
  5. La línea <img src="" alt="Mi imagen de prueba"> es el código HTML que inserta una imagen en la página. Necesitamos decirle al HTML dónde está la imagen. La imagen está dentro del directorio images, que está en el mismo directorio que index.html. Para recorrer la estructura del archivo desde index.html hasta nuestra imagen, la ruta del archivo que necesitamos es images/nombre-archivo-imagen. Por ejemplo, nuestra imagen se llama firefox-icon.png, por lo que la ruta del archivo es images/firefox-icon.png.
  6. +
  7. Inserta la ruta del archivo en tu código HTML entre las comillas dobles del código src="".
  8. +
  9. Guarda tu archivo HTML, luego cárgalo en tu navegador web (haz doble clic en el archivo). ¡Deberías ver tu nueva página web mostrando tu imagen!
  10. +
+ +

Una captura de pantalla del sitio web básico que muestra solo el logotipo de Firefox: un zorro en llamas envolviendo el mundo

+ +

Algunas reglas generales para las rutas de archivo:

+ + + +

Por ahora, esto es todo lo que necesitas saber.

+ +
+

Nota: El sistema de archivos de Windows tiende a utilizar barras invertidas, no barras diagonales, p. ej. C:\windows. Esto no importa en HTML, incluso si estás desarrollando tu sitio web en Windows, debes usar barras diagonales en tu código.

+
+ +

¿Qué más se debería hacer?

+ +

Eso es todo por ahora. La estructura de tu directorio debería verse así:

+ +

Una estructura de archivos en mac os x finder, que muestra un directorio de imágenes con una imagen, directorios de estilos y scripts vacíos, y un archivo index.html

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/What_will_your_website_look_like", "Learn/Getting_started_with_the_web/HTML_basics", "Learn/Getting_started_with_the_web")}}

+ + + +

En este módulo

+ + diff --git a/files/es/learn/getting_started_with_the_web/publishing_your_website/index.html b/files/es/learn/getting_started_with_the_web/publishing_your_website/index.html new file mode 100644 index 0000000000..9dbfe88d7e --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/publishing_your_website/index.html @@ -0,0 +1,195 @@ +--- +title: Publicar tu sitio web +slug: Learn/Getting_started_with_the_web/Publishing_your_website +tags: + - Aprender + - Aprendiz + - Dropbox + - FTP + - GitHub + - Publicacion + - Sitio Web + - Web + - Web Hosting + - publicar + - web server +translation_of: Learn/Getting_started_with_the_web/Publishing_your_website +--- +

{{LearnSidebar()}}

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/JavaScript_basics", "Learn/Getting_started_with_the_web/How_the_Web_works","Learn/Getting_started_with_the_web")}}

+ +
+

Una vez que termines de escribir tu código y organizar los archivos que forman parte de tu sitio, debes ponerlo en línea para que la gente pueda consultarlo. Este artículo muestra cómo conseguir de manera sencilla que tu código esté en línea.

+
+ +

¿Cuáles son las opciones?

+ +

Publicar un sitio no es un tema sencillo, principalmente porque hay muchas maneras diferentes de hacerlo. En este artículo no se trata de ver todos los modos posibles. En su lugar, discutiremos los pros y contras de tres amplias estrategias desde el punto de vista de un principiante, y luego debes seleccionar qué método usarás.

+ +

Obtener alojamiento y un nombre de dominio

+ +

Si deseas un control total sobre tu sitio web publicado, probablemente necesitarás gastar dinero para comprar:

+ + + +

Muchos sitios web profesionales toman esta opción.

+ +

Además, necesitarás un programa de protocolo de transferencia de archivo (File Transfer Protocol, FTP) para transferir los archivos que conforman tu sitio web al servidor (mira más detalles de cuánto puede costar: software). Los programas FTP varían ampliamente, pero en general tienes que conectarte a tu servidor web contratado mediante detalles proporcionados por tu empresa de alojamiento (por ejemplo: nombre de usuario, contraseña, nombre del host). Una vez conectado con el servidor web el programa te mostrará tus archivos locales y los archivos del servidor web en dos ventanas y te proporcionará una forma de transferir los archivos de un lado a otro.

+ +

+ +

Consejos para elegir alojamienoto y dominio

+ + + +

Utilizar una herramienta en línea como GitHub o Dropbox

+ +

Algunas herramientas te permiten publicar tu sitio en línea:

+ + + +

A diferencia de la mayoría de alojamientos (servicios de hosting), tales herramientas son por lo general libres de utilizar, pero solo permiten un conjunto de funciones limitadas.

+ +

Utilizar un entorno basado en web como CodePen

+ +

Existe un número de aplicaciones web que emulan un entorno de desarrollo de sitios web, permitiendo que ingreses tu código HTML, CSS y Javascript y luego muestran los resultados de dicho código como un sitio web, ¡todo en una pestaña del navegador! En términos generales, estas herramientas son bastante sencillas, geniales para aprender, buenas para compartir código (por ejemplo, si quieres compartir con alguien una técnica o pedir ayuda en la depuración del código) y gratuitas para las funciones básicas. Además, mantienen tu página renderizada en una única dirección web. Sin embargo, las características básicas son muy limitadas y estas aplicaciones usualmente no proveen espacio de almacenamiento para recursos (como imágenes).

+ +

Prueba con algunos de estos ejemplos y observa cuál es el que mejor se adapta a tu gusto:

+ + + +

+ +

Publicar a través de GitHub

+ +

Explicados estos tres métodos veamos ahora cómo publicar fácilmente, de forma muy visual e intuitiva, o bien por medio de comandos, tu sitio a través de GitHub Pages (en inglés).

+ +

De manera visual y sin necesidad de más herramientas

+ +

Esta no es la única manera, pero sí la que te permite poner manos a la obra inmediatamente.

+ +
    +
  1. Si aún no lo has hecho da de alta una cuenta en GitHub. Es simple y sencillo, solo debes verificar tu dirección de correo electrónico.
  2. +
  3. Una vez registrado, ingresa a tu cuenta en GitHub.com con tu usuario y contraseña suministrados al crear tu cuenta.
  4. +
  5. A continuación, necesitas crear un nuevo repositorio para tus archivos. Haz clic en el signo más (+) en la parte superior derecha de la página inicial de GitHub y selecciona New Repository (Nuevo repositorio).
  6. +
  7. En esta página, en la casilla Repository name (Nombre del repositorio), ingresa usuario.github.io, donde usuario es tu nombre de usuario. Así por ejemplo, nuestro amigo Bob Smith ingresaría bobsmith.github.io.
  8. +
  9. Opcionalmente escribe una corta descripción de tu sitio web en el campo Description para que recuerdes cuál es la temática que tratarás en él y selecciona la casilla de verificación Public (Público) si quieres que cualquier persona pueda ver los resultados de las ediciones que haces al sitio web que estás creando.
  10. +
  11. Marca la casilla de verificación Initialize this repository with a README (Inicializar este repositorio con un README (LÉAME)). Esto te permitirá clonar inmediatamente el repositorio a tu equipo. ¡Si vas a transferir tus archivos desde tu equipo al servidor de GitHub a través de un cliente de FTP (como se explica en la sección Subir tus archivos a GitHub a través de la línea de comandos, a continuación), no debes realizar este paso!
  12. +
  13. Da clic en Create repository (Crear repositorio).
  14. +
  15. Arrastra y suelta el contenido de la carpeta de tu sitio web en tu repositorio. Cuando termines de pasar el contenido haz clic en Commit changes (Confirmar cambios). +
    +

    Nota: cerciórate que tu carpeta tiene un archivo de nombre index.html

    +
    +
  16. +
  17. En tu navegador desplázate a username.github.io para ver tu sitio web en línea. Por ejemplo, para el nombre de usuario Bob Smith, escribe bobsmith.github.io. + + +
    +

    Nota: puede que tu página web tarde unos minutos en entrar en funcionamiento. Si tu sitio web no se muestra inmediatamente, espera unos minutos e inténtalo de nuevo.

    +
    +
  18. +
+ +

Subir tus archivos a GitHub a través de la línea de comandos

+ +

No estamos diciendo que esta es la única manera, o la mejor, de publicar tu sitio, pero es gratis, decentemente simple y abarca algunas nuevas habilidades que encontrarás útiles en adelante.

+ +

Antes que nada, descarga e instala Git en tu equipo. Este paso es necesario si vas a trabajar con los archivos de tu página web en él y luego los transferirás al servidor de GitHub.

+ +

Sigue los pasos 1 a 5 y el 7 (recuerda omitir el 6) detallados en la anterior sección De manera visual y sin necesidad de más herramientas. Una vez hayas dado clic en Create repository (Crear repositorio) verás la siguiente ventana (¡no la cierres, más adelante necesitarás copiar información de allí!):

+ +

+ +

En este punto ya estarás listo para poder utilizar la línea de comandos para subir los archivos de tu repositorio a GitHub. Una línea de órdenes o de comandos es una ventana donde escribes comandos que realizarán tareas como crear archivos y ejecutar programas, en lugar de utiizar la interfaz gráfica de usuario. Se debe parecer a algo como esto:

+ +

+ +
+

Nota: si no te sientes cómodo utilizando la línea de comandos, podrías considerar usar Git graphical user interface para realizar la misma tarea.

+
+ +

Todos los sistemas operativos vienen con una herramienta de línea de comandos:

+ + + +

Aunque este procedimiento pueda parecer un poco aterrador al principio no te preocupes, pronto te darás cuenta de lo básico. Darás órdenes al equipo en el terminal escribiendo un comando y presionando Intro.

+ +
    +
  1. Apunta la línea de comandos a tu directorio sitio-prueba (o como quiera que hayas llamado al directorio que contiene tu sitio web). Para esto utiliza el comando cd (es decir, «change directory», «cambiar de directorio»). Aquí viene lo que deberías teclear si has ubicado tu sitio web en un directorio llamado sitio-prueba en tu escritorio: + +
    cd Desktop/sitio-prueba
    + +

    En Windows sería:

    + +
    cd %USERPROFILE%\Desktop\sitio-prueba
    +
  2. +
  3. Cuando la línea de comandos esté apuntando dentro del directorio de tu sitio web, teclea el siguiente comando, que indica a la herramienta de git que transforme el directorio en un repositorio de Git: +
    git init
    +
  4. +
  5. +

    A continuación, regresa a la ventana del sitio de GitHub que dejaste abierta. En esa página, la sección que interesa es …or push an existing repository from the command line. Deberías ver dos líneas de código listadas en esa sección. Copia toda la primera línea, pégala en la línea de comandos y presiona Intro. El comando debería verse similar a:

    + +
    git remote add origin https://github.com/bobsmith/bobsmith.github.io.gi
    +
  6. +
  7. A continuación, ingresa los siguientes dos comandos, presionando Intro después de cada uno. Estos preparan el código para cargar a GitHub y pedir a Git administrar estos archivos. +
    git add --all Intro
    +git commit -m 'agregando archivos a mi repositorio' Intro
    +
  8. +
  9. Finalmente, envía el codigo a GitHub tomando de la página web de GitHub en la que estás el segundo de los dos comandos del paso 3 e introdúcelo en el terminal: +
    git push -u origin master
    +
  10. +
  11. Ahora cuando vayas a la direccion de red de tu página GitHub (usuario.github.io) en una nueva pestaña del navegador ¡deberías ver tu sitio en línea! Envíala por correo-e a tus amigos y presume de tu maestría.
  12. +
+ +
+

Nota: has tocado apenas la superficie de Git. Si te quedas atascado la ayuda de GitHub en español te será de gran apoyo.

+
+ +

Conocer más de GitHub

+ +

Si deseas hacer más cambios a tu sitio y enviarlos a GitHub, luego de modificar los archivos, debes ingresar los siguientes comandos (presionando Intro después de cada uno) para enviar esos cambios a GitHub:

+ +
git add --all Intro
+git commit -m 'otro commit' Intro
+git push Intro
+ +

Puedes reemplazar el texto otro commit con un mensaje más descriptivo respecto a los cambios que hiciste.

+ +

Conclusión

+ +

En este punto, deberías tener tu página web de ejemplo disponible en una dirección web única. ¡Bien hecho!

+ +

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/JavaScript_basics", "Learn/Getting_started_with_the_web/How_the_Web_works","Learn/Getting_started_with_the_web")}}

diff --git a/files/es/learn/getting_started_with_the_web/what_will_your_website_look_like/index.html b/files/es/learn/getting_started_with_the_web/what_will_your_website_look_like/index.html new file mode 100644 index 0000000000..fb6ced116f --- /dev/null +++ b/files/es/learn/getting_started_with_the_web/what_will_your_website_look_like/index.html @@ -0,0 +1,113 @@ +--- +title: ¿Cuál será la apariencia de tu sitio Web? +slug: Learn/Getting_started_with_the_web/What_will_your_website_look_like +tags: + - Activos + - Aprender + - Composición + - Contenido + - Desaprobado + - Diseño + - Fuentes + - Imagenes + - Novato + - Planificar + - Principiante + - Tipos de Letra + - paso a paso +translation_of: Learn/Getting_started_with_the_web/What_will_your_website_look_like +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Getting_started_with_the_web/Installing_basic_software", "Learn/Getting_started_with_the_web/Dealing_with_files", "Learn/Getting_started_with_the_web")}}
+ +
+

¿Cómo se verá tu sitio web?, analiza el trabajo de planificación y diseño que debes realizar para tu sitio web antes de escribir el código, incluyendo: "¿qué información ofrece mi sitio web?", "¿qué tipos de letra y colores quiero?" y "¿qué hace mi sitio?".

+
+ +

Lo primero es lo primero: planificación

+ +

Antes de hacer nada, necesitas algunas ideas. ¿Qué debería hacer realmente tu sitio web?; Un sitio web puede hacer básicamente cualquier cosa, pero, en tu primer intento, debes mantener las cosas simples. Comenzarás creando una página web simple con un encabezado, una imagen y algunos párrafos.

+ +

Para comenzar, deberás responder estas preguntas:

+ +
    +
  1. ¿De qué trata tu sitio web?, ¿te gustan los perros, Nueva York o Pac-Man?
  2. +
  3. ¿Qué información presentas sobre el tema?; Escribe un título y algunos párrafos y piensa en una imagen que te gustaría mostrar en tu página.
  4. +
  5. ¿Cómo se ve tu sitio web, en términos simples de alto nivel?, ¿cuál es el color de fondo?, ¿qué tipo de letra es apropiado: formal, caricaturesca, atrevida y fuerte, sutil?
  6. +
+ +
+

Nota: Los proyectos complejos necesitan pautas detalladas que incluyan todos los detalles de los colores, los tipos de letra, el espacio entre los elementos de una página, el estilo de escritura adecuado, etc. Esto, a veces, se denomina guía de diseño, sistema de diseño o libro de marcas, y puedes ver un ejemplo en el Sistema de diseño de fotones de Firefox.

+
+ +

Haz un bosquejo de tu diseño

+ +

A continuación, toma papel y lápiz y dibuja aproximadamente cómo deseas que se vea tu sitio. Para tu primera página web simple, no hay mucho que esbozar, pero deberías adquirir el hábito de hacerlo ahora. Realmente ayuda, ¡no tienes que ser Van Gogh!

+ +

Bosquejo

+ +
+

Nota: Incluso en sitios web reales y complejos, los equipos de diseño suelen comenzar con bocetos en papel y luego crean maquetas digitales utilizando un editor de gráficos o tecnologías web.

+ +

Los equipos web suelen incluir tanto un diseñador gráfico como un diseñador de {{Glossary("UX", "experiencia de usuario")}} (UX). Los diseñadores gráficos ensamblan las imágenes del sitio web. Los diseñadores de experiencia de usuario tienen un papel algo más abstracto al abordar cómo los usuarios experimentarán e interactuarán con el sitio web.

+
+ +

Elige tus activos

+ +

En este punto, es bueno comenzar a reunir el contenido que eventualmente aparecerá en tu página web.

+ +

Texto

+ +

Aún debes tener los párrafos y el título de antes. Mantenlos cerca.

+ +

Color del tema

+ +

Para elegir un color, ve al Selector de color y busca un color que te guste . Al hacer clic en un color, verás un extraño código de seis caracteres como #660066. Eso se llama código hexadecimal (abreviatura de hexadecimal) y representa tu color. Copia el código en un lugar seguro por ahora.

+ +

Color del tema

+ +

Imágenes

+ +

Para elegir una imagen, ve a Imágenes Google y busca algo adecuado.

+ +
    +
  1. Cuando encuentres la imagen que deseas, haz clic en la imagen para obtener una vista ampliada de la misma.
  2. +
  3. Haz clic con el botón derecho en la imagen (Ctrl+clic en una Mac), elige Guardar imagen como... y elige un lugar seguro para guardar tu imagen. Alternativamente, copia la dirección web de la imagen de la barra de direcciones de tu navegador para su posterior uso.
  4. +
+ +

Imágenes

+ +

Ten en cuenta que la mayoría de las imágenes en la web, incluidas las de Imágenes Google, están protegidas por derechos de autor. Para reducir tu probabilidad de violar los derechos de autor, puedes utilizar el filtro de licencias de Google. Haz clic en el botón Herramientas y luego en la opción Derechos de uso resultante que aparece a continuación. Debes elegir una opción como Etiquetado para reutilización.

+ +

Etiquetado para reutilización

+ +

Tipos de letra

+ +

Para elegir un tipo de letra:

+ +
    +
  1. Ve a Google Fonts y desplázate hacia abajo en la lista hasta que encuentres una que te guste. También puedes utilizar los controles de la derecha para filtrar aún más los resultados.
  2. +
  3. Haz clic en el icono "más" (Agregar a) junto al tipo de letra que desees.
  4. +
  5. Haz clic en el botón "*Familia seleccionada" en el panel en la parte inferior de la página ("*" depende de cuántos tipos de letra hayas seleccionado).
  6. +
  7. En el cuadro emergente, puedes ver y copiar las líneas de código que Google te brinda en tu editor de texto para guardarlas para más adelante.
  8. +
+ +

Archivos de tipo de letra

+ +

Tipos de letra

+ +

{{PreviousMenuNext("Learn/Getting_started_with_the_web/Installing_basic_software", "Learn/Getting_started_with_the_web/Dealing_with_files", "Learn/Getting_started_with_the_web")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/herramientas_y_pruebas/cross_browser_testing/index.html b/files/es/learn/herramientas_y_pruebas/cross_browser_testing/index.html new file mode 100644 index 0000000000..73bd6299a1 --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/cross_browser_testing/index.html @@ -0,0 +1,39 @@ +--- +title: Cross browser testing +slug: Learn/Herramientas_y_pruebas/Cross_browser_testing +translation_of: Learn/Tools_and_testing/Cross_browser_testing +--- +
{{LearnSidebar}}
+ +

Este módulo se centra en probar proyectos web en diferentes navegadores. Nos fijamos en la identificación de su público objetivo (por ejemplo, qué usuarios, navegadores y dispositivos son los que más le preocupan?), cómo realizar las pruebas, los principales problemas a los que se enfrentará con los diferentes tipos de código y cómo mitigarlos, qué herramientas son las más útiles para ayudarle a probar y solucionar problemas, y cómo utilizar la automatización para acelerar las pruebas.

+ +

Prerequisitos

+ +

Debería aprender los conceptos básicos de los lenguajes HTML, CSS y JavaScript básicos antes de intentar utilizar las herramientas que se detallan aquí.

+ +

Guías

+ +
+
Introducción a la prueba de navegadores cruzados
+
Este artículo comienza el módulo proporcionando una visión general del tema de la prueba de navegadores cruzados, respondiendo a preguntas como "¿qué es la prueba de navegadores cruzados? y "¿cuáles son los tipos de problemas más comunes que se encuentran?
+
Estrategias para la realización de las pruebas
+
+

A continuación, profundizamos en la realización de pruebas, la identificación de un público objetivo (por ejemplo, qué navegadores, dispositivos y otros segmentos deben ser probados), estrategias de pruebas de baja fiabilidad (obtenga una gama de dispositivos y algunas máquinas virtuales y realice pruebas ad-hoc cuando sea necesario), estrategias de alta tecnología (automatización, uso de aplicaciones de pruebas dedicadas), y pruebas con grupos de usuarios.

+
+
Manejo de problemas comunes de HTML y CSS
+
+

Con el conjunto de escenas, ahora veremos específicamente los problemas comunes entre navegadores que encontrará en código HTML y CSS, y qué herramientas se pueden usar para evitar que ocurran problemas o para solucionarlos. Esto incluye el código de hilado, la entrega de prefijos CSS, el uso de herramientas de desarrollo de navegadores para localizar problemas, el uso de polifiltros para añadir soporte a los navegadores, la solución de problemas de diseño con capacidad de respuesta, y mucho más.

+
+
Manejo de problemas comunes de JavaScript
+
+

Ahora veremos los problemas comunes de JavaScript en todos los navegadores y cómo solucionarlos. Esto incluye información sobre el uso de herramientas de desarrollo del navegador para localizar y solucionar problemas, el uso de polifondos y bibliotecas para solucionar los problemas, el funcionamiento de las funciones modernas de JavaScript en navegadores antiguos, y mucho más.

+
+
Manejo de problemas comunes de accesibilidad
+
A continuación, nos centramos en la accesibilidad, proporcionando información sobre problemas comunes, cómo realizar pruebas sencillas y cómo utilizar las herramientas de auditoría/automatización para encontrar problemas de accesibilidad.
+
Implementación de la detección de características
+
La detección de funciones implica determinar si un navegador soporta un determinado bloque de código, y ejecutar un código diferente dependiendo de si lo hace (o no), de modo que el navegador siempre puede proporcionar una experiencia de trabajo en lugar de bloquearse/error en algunos navegadores. Este artículo detalla cómo escribir su propia detección de características simples, cómo usar una biblioteca para acelerar la implementación y características nativas para la detección de características como @supports.
+
Introducción a las pruebas automatizadas
+
La realización manual de pruebas en varios navegadores y dispositivos, varias veces al día, puede resultar tediosa y consumir mucho tiempo. Para manejar esto eficientemente, debe familiarizarse con las herramientas de automatización. En este artículo, analizamos lo que está disponible, cómo utilizar los corredores de tareas y los conceptos básicos de cómo utilizar las aplicaciones de automatización de pruebas de navegadores comerciales, como Sauce Labs y Browser Stack.
+
Configuración de su propio entorno de automatización de pruebas
+
En este artículo, le enseñaremos cómo instalar su propio entorno de automatización y ejecutar sus propias pruebas utilizando Selenium/WebDriver y una biblioteca de pruebas como Selenium-webdriver for Node. También veremos cómo integrar su entorno de pruebas local con aplicaciones comerciales como las que se comentaron en el artículo anterior.
+
diff --git a/files/es/learn/herramientas_y_pruebas/github/index.html b/files/es/learn/herramientas_y_pruebas/github/index.html new file mode 100644 index 0000000000..62646f1cc4 --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/github/index.html @@ -0,0 +1,92 @@ +--- +title: Git y GitHub +slug: Learn/Herramientas_y_pruebas/GitHub +tags: + - Aprender + - GitHub + - Principiante + - Web + - git +translation_of: Learn/Tools_and_testing/GitHub +--- +
{{LearnSidebar}}
+ +

Todos los desarrolladores utilizarán algún tipo de sistema de control de versiones ( VCS ), una herramienta que les permita colaborar con otros desarrolladores en un proyecto sin peligro de que sobrescriban el trabajo de los demás, y volver a las versiones anteriores de la base de código si existe un problema descubierto más tarde. El VCS más popular (al menos entre los desarrolladores web) es Git, junto con GitHub, un sitio que proporciona alojamiento para tus repositorios y varias herramientas para trabajar con ellos. Este módulo tiene como objetivo enseñarte lo que necesitas saber sobre ambos.

+ +

Introducción

+ +

Los VCS son esenciales para el desarrollo de software:

+ + + +

Los VCS proporcionan herramientas para satisfacer las necesidades anteriores. Git es un ejemplo de VCS, y GitHub es un sitio web + infraestructura que proporciona un servidor Git más una serie de herramientas realmente útiles para trabajar con repositorios git individuales o en equipo, como informar problemas con el código, herramientas de revisión, características de administración de proyectos tal como asignación de tareas, estados de tareas, y más.

+ +
+

Nota: Git en realidad es un sistema de control de versiones distribuido, lo cual significa que se realiza una copia completa del repositorio que contiene la base de código en tu computadora (y en la de todos los demás). Realizas cambios en tu propia copia, y luego empujas esos cambios nuevamente al servidor, donde un administrador decidirá si fusiona tus cambios con la copia maestra.

+
+ +

¿Quieres convertirte en un desarrollador web front-end?

+ +

Hemos preparado un curso que incluye toda la información esencial que necesitas para alcanzar tu objetivo.

+ +
+

Comenzar

+
+ +

Prerequisitos

+ +

Para usar Git y GitHub, necesitas:

+ + + +

En términos de conocimiento previo, no necesitas saber nada sobre desarrollo web, Git/GitHub o VCS para iniciar este módulo. Sin embargo, se recomienda que conozcas algo de codificación para que tengas conocimientos informáticos razonables y algún código para almacenar en tus repositorios.

+ +

También es preferible que tengas algunos conocimientos básicos de la terminal, por ejemplo, moverte entre directorios, crear archivos y modificar la variable del sistema PATH.

+ +
+

Nota: Github no es el único sitio/conjunto de herramientas que puedes usar con Git. Hay otras alternativas, como GitLab, que podrías probar, y también podrías intentar configurar tu propio servidor Git y usarlo en lugar de GitHub. Solo nos hemos quedado con GitHub en este curso para proporcionar una forma única que funciona.

+
+ +

Guías

+ +

Ten en cuenta que los enlaces a continuación te llevan a recursos en sitios externos. Eventualmente intentaremos tener nuestro propio curso Git/GitHub dedicado, pero por ahora, esto te ayudará a familiarizarte con el tema en cuestión.

+ +
+
Hola mundo (de GitHub)
+
Este es un buen lugar para comenzar: esta guía práctica te permite comenzar a usar GitHub, aprender los conceptos básicos de Git, como crear repositorios y ramas, realizar confirmaciones, abrir y fusionar solicitudes de extracción.
+
Manual de Git (en GitHub)
+
Este Manual de Git profundiza un poco más, explicando qué es un VCS, qué es un repositorio, cómo funciona el modelo básico de GitHub, comandos y ejemplos de Git, y más.
+
Bifurcación de proyectos (de GitHub)
+
Bifurcar proyectos es esencial cuando deseas contribuir al código de otra persona. Esta guía explica cómo.
+
Acerca de las solicitudes de extracción (de GitHub)
+
Una útil guía para administrar las solicitudes de extracción, la forma en que los cambios de código sugeridos se entregan a los repositorios de las personas para su consideración.
+
Dominando las incidencias (de GitHub)
+
Las incidencias son como un foro para tu proyecto GitHub, donde las personas pueden hacer preguntas e informar problemas, y tú puede administrar las actualizaciones (por ejemplo, asignar personas para solucionar problemas, aclarar el problema, informar a las personas que las cosas están solucionadas). Este artículo te brinda lo que necesitas saber sobre las incidencias.
+
+ +
+

Nota: Hay mucho más que puedes hacer con Git y GitHub, pero creemos que lo anterior representa lo mínimo que necesitas saber para comenzar a usar Git de manera efectiva. A medida que profundices en Git, comenzarás a darte cuenta de que es fácil equivocarse cuando comienzas a usar comandos más complicados. No te preocupes, incluso los desarrolladores web profesionales encuentran a Git confuso a veces, y a menudo resuelven problemas buscando soluciones en la web, o consultando sitios como Reglas de vuelo para Git y Dangit, ¡git!

+
+ +

Ve también

+ + diff --git a/files/es/learn/herramientas_y_pruebas/index.html b/files/es/learn/herramientas_y_pruebas/index.html new file mode 100644 index 0000000000..a147c98f65 --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/index.html @@ -0,0 +1,58 @@ +--- +title: Herramientas y pruebas +slug: Learn/Herramientas_y_pruebas +tags: + - Accesibilidad + - Aprender + - Aterrizaje + - CSS + - CodificaciónDeSecuenciasDeComandos + - HTML + - Herramientas + - JavaScript + - Navegador cruzado + - Principiante + - Pruebas de usuario + - Tema + - Testing + - automatización +translation_of: Learn/Tools_and_testing +--- +
+

{{LearnSidebar}}

+ +

Una vez que haya comenzado a sentirse cómodo programando con tecnologías web básicas (como HTML, CSS y JavaScript), y comience a adquirir más experiencia, leer más recursos y aprender más trucos y consejos, comenzará a encontrar todos tipo de herramientas, desde CSS y JavaScript ya enrollados, aplicaciones de prueba y automatización, y muchas más. A medida que sus proyectos web se vuelvan más grandes y complejos, querrá comenzar a aprovechar algunas de estas herramientas y elaborar planes de prueba confiables para su código. Esta parte del área de aprendizaje tiene como objetivo brindarle lo que necesita para comenzar y tomar decisiones informadas.

+
+ +

 

+ +

{{LearnSidebar}}

+ +

La industria de la web es un lugar emocionante para trabajar, pero no está exenta de complicaciones. Las tecnologías principales que utilizamos para crear sitios web son bastante estables ahora, pero se están agregando nuevas características todo el tiempo, y nuevas herramientas, que facilitan el trabajo con estas tecnologías y están construidas sobre estas tecnologías, aparecen constantemente. Además de eso, todavía tenemos que mantener la compatibilidad entre navegadores en la parte superior de nuestras mentes y asegurarnos de que nuestro código sigue las mejores prácticas que permiten que nuestros proyectos funcionen en diferentes navegadores y dispositivos que nuestros usuarios utilizan para navegar por la Web, y ser utilizable por personas con discapacidad.

+ +

Determinar qué herramientas debería usar puede ser un proceso difícil, por lo que hemos escrito este conjunto de artículos para informarle qué tipos de herramientas están disponibles, qué pueden hacer por usted y cómo hacer uso de los favoritos actuales de la industria.

+ +

 

+ +
+

Nota: Debido a que aparecen nuevas herramientas y las antiguas pasan de moda todo el tiempo, hemos redactado deliberadamente este material para que sea lo más neutral posible. Queremos enfocarnos ante todo en los tipos generales de tareas que estas herramientas lo ayudarán a lograr. y seguir prescribiendo herramientas específicas al mínimo. Obviamente, necesitamos mostrar el uso de las herramientas para demostrar técnicas específicas, pero ten en cuenta que no necesariamente recomendamos estas herramientas como la mejor o la única forma de hacer las cosas; en la mayoría de los casos, existen otras formas, pero queremos brindarte una idea clara. Metodología que funciona.

+
+ +

Camino de aprendizaje

+ +

 

+ +

Debería aprender los conceptos básicos de los lenguajes HTML, CSS, y JavaScript antes de intentar usar las herramientas que se detallan aquí. Por ejemplo, deberá conocer los fundamentos de estos idiomas antes de comenzar a depurar problemas en códigos web complejos, o hacer un uso efectivo de las bibliotecas de JavaScript, o escribir pruebas y ejecutarlas en su código utilizando corredores de prueba, etc.

+ +

Primero necesitas una base sólida.

+ +

 

+ +

Módulos

+ +
+
Herramientas de desarrollo web en el mundo real (TBD)
+
En este módulo, exploramos los diferentes tipos de herramientas de desarrollo web disponibles. Esto incluye la revisión de los tipos de tareas más comunes a las que se le puede pedir que resuelva, cómo pueden encajar en un flujo de trabajo y las mejores herramientas disponibles actualmente para llevar a cabo esas tareas.
+
Pruebas de navegadores cruzados
+
Este módulo analiza específicamente el área de prueba de proyectos web en diferentes navegadores. Aquí vemos cómo identificar a su público objetivo (por ejemplo, qué usuarios, navegadores y dispositivos necesita preocuparse más), cómo realizar las pruebas, los principales problemas que enfrentará con los diferentes tipos de código y cómo solucionar o mitigue esos problemas, qué herramientas son más útiles para ayudarlo a probar y solucionar problemas, y cómo utilizar la automatización para acelerar las pruebas.
+
diff --git a/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/index.html b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/index.html new file mode 100644 index 0000000000..e9bdd36eca --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/index.html @@ -0,0 +1,133 @@ +--- +title: Entendiendo los frameworks de JavaScript del lado del cliente +slug: Learn/Herramientas_y_pruebas/Lado-del-cliente_JavaScript_frameworks +tags: + - Aprender + - Principiante +translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks +--- +
{{LearnSidebar}}
+ +

Los frameworks de JavaScript son una parte esencial del desarrollo web front-end moderno, los cuales proveen a los desarrolladores herramientas probadas y testeadas para la creación de aplicaciones web interactivas y escalables. Muchas empresas modernas utilizan frameworks como parte estándar de sus herramientas, por lo que muchos trabajos de desarrollo front-end en la actualidad requieren experiencia en frameworks.

+ +

Como aspirante a desarrollador front-end, puede resultar difícil saber por dónde empezar cuando se trata de aprender sobre frameworks; hay muchos frameworks diferentes para elegir, nuevas opciones surgen todo el tiempo. En su mayoría funcionan de forma similar, pero hacen algunas cosas de manera diferente, y hay algunas cosas específicas con las que se debe tener cuidado a la hora de usar frameworks.

+ +

En esta serie de artículos, tenemos como objetivo brindarte un punto de partida cómodo que te sirva de ayuda para comenzar a aprender sobre frameworks. Nuestra intención no es enseñarte, de manera exhaustiva, todo lo que se necesita saber sobre React/ReactDOM, o Vue, o algún otro framework en específico; la documetación de los equipos de los frameworks (entre otros recursos) ya cumplen esta función. En su lugar, queremos brindarte respaldo y responder primero a preguntas más fundamentales como:

+ + + +

Después de esto, proveeremos algunos tutoriales que cubren los aspectos básicos de algunos de los diferentes frameworks que existen, de manera que puedas tener el contexto y la familiaridad suficientes para poder empezar a profundizar por tu propia cuenta. Queremos que avances y aprendas sobre los frameworks de manera pragmática, de forma tal que se tengan presente las buenas prácticas esenciales de la plataforma web, como lo es la accesibilidad.

+ +

Empieza ahora con "Introducción a los frameworks del lado del cliente"

+ +

Prerrequisitos

+ +

Antes de intentar aprender sobre los frameworks del lado del cliente, es recomendable que conozcamos los conceptos básicos de los principales lenguajes de la web: HTML, CSS, y —especialmente— JavaScript.

+ +

Como resultado, tu código será más consistente y profesional, por lo que podrás solucionar problemas con mayor confianza si comprende las características fundamentales de la plataforma web sobre las que se basan los frameworks.

+ +

Guías introductorias

+ +
+
1. Introducción a los frameworks del lado del cliente
+
Comenzamos nuestro estudio sobre los frameworks con una descripción general del área, repasando un poco de historia sobre JavaScript y los frameworks, por qué estos existen, y qué nos brindan; por donde empezar al momento de escoger un framework por aprender y qué alternativas existen a los frameworks del lado del cliente.
+
2. Características principales de los frameworks
+
Cada framework destacado de JavaScript tiene un enfoque diferente para actualizar el DOM, manejar los eventos del navegador, y brindarte una experiencia de desarrollo satisfactoria. En este artículo, exploraremos las características principales de "los cuatro grandes" frameworks, observando cómo estos tienden a operar desde un nivel alto, al igual que las diferencias entre ellos.
+
+ +

Tutoriales de React

+ +
+

Nota: Los tutoriales de React se probaron por última vez en mayo de 2020, con React/ReactDOM 16.13.1 y create-react-app 3.4.1.

+ +

Si necesitas comparar tu código con nuestra versión, puedes encontrar una versión terminada de la muestra del código de la aplicación React en nuestro repositorio todo-react. Para una versión en vivo, consulta https://mdn.github.io/todo-react-build/.

+
+ +
+
1. Primeros pasos en React
+
En este artículo conoceremos React. Descubriremos algunos detalles sobre su trasfondo y casos de uso, configuraremos una cadena básica de herramientas para React en nuestra computadora local, crearemos y jugaremos con una aplicación inicial sencilla, mientras aprendemos —durante el proceso— un poco acerca de cómo funciona React.
+
2. Comenzando con nuestra lista de tareas de React
+
Digamos que se nos ha encomendado la tarea de crear una prueba de concepto (Proof of Concept — PoC) en React: una aplicación que permita a los usuarios agregar, editar y eliminar tareas en las que se quiera trabajar, pero que también permita marcar las tareas como completadas sin eliminarlas. Este artículo te guiará en la organización de la estructura y los estilos básicos del componente App, de manera que esté listo para la definición e interactividad de componentes individuales, los cuales agregaremos más adelante.
+
3. Basando nuestra aplicación React en componentes
+
Hasta este momento, nuestra aplicación no hace gran cosa. Antes de que podamos hacerla funcionar, tenemos que dividirla en componentes descriptivos y manejables. React no tiene reglas estrictas para lo que, se considera o no, un componente, ¡eso depende de ti! En este artículo, te mostraremos una forma raznoable de dividir nuestra aplicación en componentes.
+
4. Interactividad en React: eventos y estado
+
Habiendo elaborado nuestro plan de componentes, es hora de comenzar a actualizar nuestra aplicación, para que pase de ser una interfaz de usuario completamente estática a una que nos permita, realmente, interactuar y cambiar las cosas. Es eso mismo lo que haremos en este artículo, profundizando en los eventos y el estado a medida que avancemos.
+
5. Interactividad en React: edición, filtrado, renderizado condicional
+
A medida que nos acercamos al final de nuestro viaje en React (al menos por ahora), agregaremos los toques finales a las áreas principales de funcionalidad en nuestra aplicación de lista de tareas. Esto incluye permitir la edición de tareas existentes y el filtrado de la lista de tareas entre todas las tareas, las completadas, y las incompletas. A lo largo del capítulo, veremos la renderización condicional de la interfaz de usuario.
+
6. Accesibilidad en React
+
En el artículo final de nuestro tutorial, nos enfocaremos en la accesibilidad (broma intencional), incluyendo la gestión del enfoque en React, la cual puede mejorar la usabilidad y reducir la confusión para usuarios que navegan tanto, a través de lectores de pantalla, como solo del teclado.
+
7. Recursos sobre React
+
En nuestro artículo final, te brindamos una lista de recursos sobre React, los cuales podrás utilizar para avanzar más en tu aprendizaje.
+
+ +

Tutoriales de Ember

+ +
+

Nota: Los tutoriales de Ember se probaron por última vez en mayo de 2020, con Ember/Ember CLI versión 3.18.0.

+ +

Si necesitas comparar tu código con nuestra versión, puedes encontrar una versión terminada de la muestra del código de la aplicación Ember en nuestro repositorio ember-todomvc-tutorial. Para una versión en vivo, consulta https://nullvoxpopuli.github.io/ember-todomvc-tutorial/ (esto también incluye algunas características adicionales que no se cubren en este tutorial).

+
+ +
+
1. Primeros pasos en Ember
+
En nuestro primer artículo de Ember veremos cómo funciona Ember y para qué resulta útil, instalaremos la cadena de herramientas de Ember de manera local, crearemos una aplicación de muestra, y luego realizaremos una configuración inicial para prepararla para el desarrollo.
+
2. Estructura de una aplicación Ember y cómo se basa en componentes
+
En este artículo, continuaremos planificando la estructura de nuestra aplicación Ember TodoMVC, agregando el HTML necesario y luego dividiendo esa estructura HTML en componentes.
+
3. Interactividad de Ember: eventos, clases, y estado
+
En este punto, comenzaremos a agregar un poco de interactividad a nuestra aplicación, dándole la capacidad de agregar y mostrar nuevos elementos de tareas por hacer. A medida que avanzamos, veremos el uso de eventos en Ember, la creación de clases de componentes para contener código JavaScript que controle las funciones interactivas, y la configuración de un servicio para hacer seguimiento del estado de los datos de nuestra aplicación.
+
4. Interactividad de Ember: funcionalidad del footer, renderizado condicional
+
Ahora es momento de comenzar a abordar la funcionalidad del footer en nuestra aplicación. Aquí haremos que el contador de tareas pendientes se actualice de manera que muestre el número correcto de tareas pendientes por completar, y aplicaremos correctamente los estilos a las tareas completadas (es decir, aquellos donde la casilla de verificación ha sido marcada). También conectaremos nuestro botón "Borrar completados". A lo largo del capítulo, aprenderemos sobre el uso de la renderización condicional en nuestras plantillas.
+
5. Enrutamiento en Ember
+
En este artículo aprendemos sobre enrutamiento o el filtrado basado en URL, como a veces se lo denomina. Lo usaremos para proporcionar una URL única para cada una de las tres vistas de tareas: "Todas", "Activas" y "Completadas".
+
6. Recursos sobre y solución de problemas
+
En nuestro artículo final sobre Ember, te proporcionamos una lista de recursos que puedes utilizar para avanzar más en tu aprendizaje, además de información útil para la solución problemas y otra información.
+
+ +

Tutoriales de Vue

+ +
+

Nota: Los tutoriales de Vue se probaron por última vez en mayo de 2020, con Vue 2.6.11.

+ +

Si necesitas comparar tu código con nuestra versión, puedes encontrar una versión terminada de la muestra del código de la aplicación Vue en nuestro repositorio todo-vue. Para una verisón en vivo, consulta https://mdn.github.io/todo-vue/dist/.

+
+ +
+
1. Primeros pasos en Vue
+
A continuación, presentamos Vue, el tercero de nuestros frameworks. En este artículo, veremos un poco sobre el origen de Vue, aprenderemos cómo instalarlo y crear un nuevo proyecto, estudiaremos la estructura de alto nivel de todo el proyecto y de un componente individual, veremos cómo ejecutar el proyecto localmente y prepararlo para comenzar a construir nuestro ejemplo.
+
2. Creando nuestro primer componente de Vue
+
Ahora es momento de profundizar en Vue y crear nuestro propio componente personalizado: comenzaremos creando un componente para representar cada elemento en la lista de tareas. Durante el artículo, aprenderemos sobre algunos conceptos importantes, como llamar a componentes dentro de otros componentes, pasarles datos a través de props y guardar el estado de los datos.
+
3. Renderizando una lista de componentes de Vue
+
En este punto, tenemos un componente completamente funcional; ahora estamos listos para agregar varios componentes ToDoItem a nuestra aplicación. En este artículo, veremos cómo agregar un conjunto de datos de elementos de tareas a nuestro componente App.vue, el cual luego repasaremos en bucle, mostrando dentro de los componentes de ToDoItem mediante el uso de la directiva v-for.
+
4. Agregar una nueva forma de tareas pendientes: eventos, métodos y modelos de Vue
+
Ahora tenemos datos de muestra listos y un ciclo que toma cada bit de datos y lo renderiza dentro de un ToDoItem en nuestra aplicación. Lo que realmente necesitamos a continuación es la capacidad de permitirle a nuestros usuarios que introuduzcan sus propios elementos de tareas pendientes en la aplicación, y para ello, necesitaremos un <input> de texto, un evento para efectuar una vez se envíen los datos, un método por accionar al momento del envío para agregar los datos y volver a renderizar la lista, y un modelo para controlar los datos. Esto es lo que cubriremos en este artículo.
+
5. Agregando estilos a los componentes de Vue con CSS
+
Por fin ha llegado el momento de hacer que nuestra aplicación luzca un poco mejor. En este artículo, exploraremos las diferentes formas de agregar estilos a los componentes de Vue con CSS.
+
6. Usando propiedades calculadas de Vue
+
En este artículo, agregaremos un contador que muestre el número de tareas completadas, utilizando una función de Vue llamada propiedades calculadas. Estos funcionan de manera similar a los métodos, pero solo se vuelven a ejecutar cuando cambia una de sus dependencias.
+
7. Renderización condicional en Vue: editando tareas existentes
+
Ahora es momento de agregar una de las principales piezas de la funcionalidad que aún nos falta: la capacidad de editar tareas existentes. Para hacer esto, aprovecharemos las capacidades de renderizado condicional de Vue, es decir, v-if y v-else, los cuales nos permiten alternar entre la vista de una tarea existente y una vista de edición donde podremos actualizar las etiquetas de las tareas. También veremos cómo agregar funcionalidad para eliminar tareas.
+
8. Gestión de enfoque con Vue refs
+
Ya estamos cerca de terminar con Vue. La última funcionalidad a considerar es la gestión del enfoque, o dicho de otra manera, cómo podemos mejorar la accesibilidad de nuestra aplicación desde el teclado. Veremos el uso de Vue refs para manejar esto, una característica avanzada que nos permite tener acceso directo a los nodos DOM subyacentes debajo del DOM virtual, o acceso directo desde un componente a la estructura DOM interna de un componente interno.
+
9. Recursos sobre Vue
+
Ahora, completaremos nuestro estudio de Vue brindándote una lista de recursos que podrás utilizar para avanzar en tu aprendizaje, además de algunos otros consejos útiles.
+
+ +

¿Cuales frameworks hemos escogido?

+ +

Hacemos pública nuestra serie inicial de artículos con guías enfocadas en tres de los principales frameworks que existen: React/ReactDOM, Ember, y Vue. Esto se debe a varias un razones:

+ + + +

Queremos decir esto desde un principio: no hemos escogido los frameworks en los que nos estamos enfocando porque pensamos que son los mejores o porque los respaldamos de alguna manera. Simplemente, consideramos que obtienen una puntuación alta de acuerdo a los criterios anteriores.

+ +

Ten en cuenta que esperábamos poder incluir más frameworks en la publicación inicial, pero que decidimos publicar el contenido y agregar, más adelante, otras guías, en lugar de retrasarlo más. Si tu framework favorito no se encuentra listado en este contenido y te gustaría ayudar a cambiar esto, ¡no dudes en discutirlo con nosotros! Puedes contactarnos a través de Matrix, o Discourse, o enviarnos un correo electrónico a la lista mdn-admins.

diff --git a/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/react_getting_started/index.html b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/react_getting_started/index.html new file mode 100644 index 0000000000..09c28f11a9 --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/react_getting_started/index.html @@ -0,0 +1,476 @@ +--- +title: Primeros pasos en React +slug: >- + Learn/Herramientas_y_pruebas/Lado-del-cliente_JavaScript_frameworks/React_getting_started +tags: + - Aprender + - Aprendiz + - Principiante +translation_of: >- + Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
+ +

En este artículo conoceremos React. Descubriremos algunos detalles sobre su trasfondo y casos de uso, configuraremos una cadena básica de herramientas para React en nuestra computadora local, crearemos y jugaremos con una aplicación inicial sencilla, mientras aprendemos —durante el proceso— un poco acerca de cómo funciona React.

+ + + + + + + + + + + + +
Prerrequisitos: +

Familiaridad con los lenguajes HTML, CSS, y JavaScript, conocimiento del terminal/línea de comandos.

+ +

React usa una sintaxis HTML-en-JavaScript llamada JSX (JavaScript y XML). Estar familiarizado con HTML y JavaScript te ayudará a aprender JSX, y a identificar —en una mejor manera— si los errores en tu aplicación están relacionados con JavaScript o con el más específico dominio de React.

+
Objetivo:Configurar un entorno de desarrollo local para React, crear una aplicación inicial, y entender los aspectos básicos de su funcionamiento.
+ +

Hola, React

+ +

Como su eslogan oficial señala, React es una biblioteca para construir interfaces de usuario. React no es un framework — ni siquiera se limita a la web. React es utilizado con otras bibliotecas para renderizar en ciertos entornos. Por ejemplo, React Native puede usarse para desarrollar aplicaciones móviles; React 360 permite crear aplicaciones de realidad virtual; además de otras posibilidades.

+ +

Al desarrollar para la web, los desarrolladores usan React en conjunto con ReactDOM. React y ReactDOM son, a menudo, considerados al igual que —y utilizados para resolver los mismo problemas que— otros verdaderos frameworks de desarrollo web. Cuando nos referimos a React como un "framework", estamos trabajando con este significado coloquial.

+ +

El objetivo principal de React es minimizar los errores que ocurren cuando los desarrolladores construyen interfaces de usuario. Esto lo hace mediante el uso de componentes — piezas de código lógicas y auto-contenidas que describen una parte de la interfaz del usuario. Estos componentes se pueden juntar para crear una interfaz de usuario completa, y React abstrae la mayor parte del trabajo de renderizado, permitiéndote enfocarte en el diseño de la interfaz.

+ +

Casos de uso

+ +

A diferencia de los otros frameworks vistos en este módulo, React no impone reglas estrictas sobre convenciones de código u organización de archivos. Esto le permite a los equipos establecer las convenciones que funcionen mejor para ellos y adoptar React de la manera en que deseen. React puede manejar un solo botón, algunas piezas de una interfaz o la interfaz de usuario completa de una aplicación.

+ +

Si bien React puede usarse para pequeñas piezas de una interfaz, no resulta tan sencillo "introducirlo" en una aplicación como sería el caso de una biblioteca como jQuery —o incluso de un framework, como Vue—, por lo que viene a ser más abordable cuando construimos una aplicación completamente con React.

+ +

Además, muchos de los beneficios de la experiencia del desarrollador de una aplicación React, como codificar interfaces con JSX, requieren un proceso de compilación. Agregar un compilador como Babel a un sitio web hace que el código se ejecute de manera lenta, por lo que los desarrolladores a menudo configuran dichas herramientas con un paso de compilación. Podrá decirse que React tiene un gran requisito de herramientas, pero se puede aprender.

+ +

Este artículo se enfocará en el caso de uso de usar React para renderizar la interfaz de usuario completa de una aplicación, usando herramientas proporcionadas por la propia herramienta de Facebook create-react-app.

+ +

¿Cómo React usa JavaScript?

+ +

React utiliza características modernas de JavaScript para muchos de sus patrones. El punto donde más se aleja de JavaScript se refleja en el uso de la sintaxis JSX, la que, a su vez, amplía la sintaxis de JavaScript para que código similar a HTML pueda formar parte del mismo. Por ejemplo:

+ +
const heading = <h1>Mozilla Developer Network</h1>;
+ +

Esta constante "heading" se conoce como una expresión JSX. React puede usarla para representar la etiqueta <h1> en nuestra aplicación.

+ +

Supongamos que, por razones semánticas, queremos envolver nuestro encabezado en una etiqueta <header>. El enfoque JSX nos permite anidar nuestros elementos entre sí, tal como lo hacemos con HTML:

+ +
const header = (
+  <header>
+    <h1>Mozilla Developer Network</h1>
+  </header>
+);
+ +
+

Nota: Los paréntesis en el fragmento anterior no son exclusivos de JSX y no tienen ningún efecto en la aplicación. Son una señal para ti (y tu computadora) de que las múltiples líneas de código que contiene forman parte de una misma expresión. También podríamos escribir la expresión del encabezado de esta manera:

+ +
const header = <header>
+    <h1>Mozilla Developer Network</h1>
+</header>
+ +

Sin embargo, esto luce un poco raro, ya que la etiqueta <header> que inicia la expresión no tiene sangría en la misma posición que su correspondiente etiqueta de cierre.

+
+ +

Por supuesto, tu navegador no puede leer JSX sin ayuda. Al compilarla (usando una herramienta como BabelParcel), nuestra expresión de encabezado se vería así:

+ +
const header = React.createElement("header", null,
+  React.createElement("h1", null, "Mozilla Developer Network")
+);
+ +

Es posible omitir el paso de la compilación y usar React.createElement() para codificar la interfaz de usuario tú mismo. Sin embargo, al hacer esto, perderías el beneficio declarativo de JSX y tu código resultaría más difícil de leer. La compilación es un paso adicional en el proceso de desarrollo, pero muchos desarrolladores de la comunidad React piensan que la legibilidad de JSX vale la pena. Además, las herramientas populares hacen que la compilación de JSX a JavaScript sea parte de su proceso de configuración. No tendrás que configurar la compilación tú mismo, a menos que así lo quieras.

+ +

Dado que JSX es una combinación de HTML y JavaScript, algunos desarrolladores lo encuentran intuitivo. Otros dicen que su naturaleza combinada lo hace confuso. Sin embargo, una vez que te sientas cómodo con JSX, te permitirá crear interfaces de usuario de forma más rápida e intuitiva, y permitirá que otros comprendan mejor tu base de código de un vistazo.

+ +

Para leer más sobre JSX, consulta el artículo JSX en profundidad del equipo de React.

+ +

Configurando tu primera aplicación React

+ +

Hay muchas maneras de usar React, pero usaremos la herramienta create-react-app de la interfaz de línea de comandos (CLI, por sus siglas en inglés), como se mencionó anteriormente, la cual acelera el proceso de desarrollo de una aplicación React al instalar algunos paquetes y crear algunos archivos por ti, manejando las herramientas descritas anteriormente.

+ +

Es posible agregar React a un sitio website sin usar create-react-app copiando algunos elementos <script> en un archivo HTML, pero la CLI de create-react-app es un punto de partida común para las aplicaciones React. Su uso te permitirá dedicar más tiempo a crear tu aplicación y menos a preocuparte por la configuración.

+ +

Requerimientos

+ +

Para usar create-react-app, necesitas tener instalado Node.js. Se recomienda utilizar la versión de soporte a largo plazo (LTS, por sus siglas en inglés). Node incluye npm (el administrador de paquetes de nodos), y npx (el ejecutor de paquetes de nodos).

+ +

También puedes usar el administrador de paquetes Yarn como alternativa, pero asumiremos que estarás usando npm en estos tutoriales. Consulta Conceptos básicos de administración de paquetes para obtener más información sobre npm y yarn.

+ +

Si estás usando Windows, necesitarás instalar algún software para darle paridad con el terminal Unix/macOS, y así poder usar los comandos del terminal mencionados en este tutorial. Gitbash (el cual viene como parte del conjunto de herramientas git para Windows) o el Subsistema de Windows para Linux (WSL, por sus siglas en inglés) son ambos adecuados. Consulte el Curso intensivo de línea de comandos para obtener más información sobre estos y sobre los comandos de terminal en general.

+ +

También ten en cuenta que React y ReactDOM producen aplicaciones que solo funcionan en un conjunto bastante moderno de navegadores (IE9+ a través de algunos polyfills). Se recomienda el uso de un navegador moderno como Firefox, Safari o Chrome cuando trabajes con estos tutoriales.

+ +

Además, consulta lo siguiente para obtener más información:

+ + + +

Inicializando tu aplicación

+ +

create-react-app recibe un argumento: el nombre que te gustaría darle a tu aplicación. create-react-app usa este nombre para crear una nueva carpeta, luego crea los archivos necesarios dentro de la misma. Asegúrate de cd al lugar donde te gustaría que se guarde tu aplicación en tu disco duro, luego ejecuta lo siguiente en tu terminal:

+ +
npx create-react-app moz-todo-react
+ +

Esto crea una carpeta moz-todo-react, y hace varias cosas dentro de la misma:

+ + + +
+

Nota: si tienes instalado el administrador de paquetes yarn, create-react-app lo usará por defecto en lugar de npm. Si tienes ambos administradores de paquetes instalados y quieres, explícitamente, usar npm, puedes agregar el indicador --use-npm cuando ejecutes create-react-app:

+ +
npx create-react-app moz-todo-react --use-npm
+
+ +

create-react-app mostrará una serie de mensajes en tu terminal mientras opera, ¡lo cual es normal! Esto puede tardar unos minutos, por lo que ahora podría ser un buen momento para preparar una taza de té.

+ +

Una vez completado el proceso, cd a la carpeta moz-todo-react y ejecuta el comando npm start. Los scripts instalados por create-react-app comenzarán a servirse en un servidor local en localhost:3000 y abrirán la aplicación en una nueva pestaña del navegador. Tu navegador mostrará algo como esto:

+ +

Screenshot of Firefox MacOS, open to localhost:3000, showing the default create-react-app application

+ +

Estructura de la aplicación

+ +

create-react-app nos provee todo lo que necesitamos para desarrollar una aplicación React. Su estructura inicial de archivos luce así:

+ +
moz-todo-react
+├── README.md
+├── node_modules
+├── package.json
+├── package-lock.json
+├── .gitignore
+├── public
+│   ├── favicon.ico
+│   ├── index.html
+│   └── manifest.json
+└── src
+    ├── App.css
+    ├── App.js
+    ├── App.test.js
+    ├── index.css
+    ├── index.js
+    ├── logo.svg
+    └── serviceWorker.js
+ +

La carpeta src es donde pasaremos la mayor parte de nuestro tiempo, ya que es donde reside el código fuente de nuestra aplicación.

+ +

La carpeta public contiene archivos que serán leidos por tu navegador mientras desarrollas la aplicación; el más importante de ellos es index.html. React introduce tu código en este archivo de manera que tu navegador pueda ejecutarlo. Hay alguno que otro marcado que ayuda a create-react-app a funcionar, así que ten cuidado de no editarlo a menos que sepas lo que estás haciendo. Deberías cambiar el texto dentro del elemento <title> en este archivo para reflejar el título de tu aplicación. ¡Los títulos de página precisos son importantes para la accesibilidad!

+ +

La carpeta public también será publicada cuando crees y despliegues una versión para producción de tu aplicación. No cubriremos el despliegue en este tutorial, pero deberías poder usar una solución similar a la descrita en nuestro tutorial Despliegue de nuestra aplicación.

+ +

El archivo package.json contiene información sobre nuestro proyecto que Node.js/npm usa para mantenerlo organizado. Este archivo no es exclusivo de las aplicaciones React; create-react-app simplemente lo completa. No es necesario que entiendas este archivo en lo absoluto para completar este tutorial, sin embargo, si deseas obtener más información al respecto, puedes leer What is the file `package.json`? en NodeJS.org; también hablamos de ello en nuestro tutorial Conceptos básicos de administración de paquetes.

+ +

Explorando nuestro primer componente React — <App/>

+ +

En React, un componente es un módulo reutilizable que representa una parte de nuestra aplicación. Estas partes pueden ser grandes o pequeñas, pero, generalmente, están bien definidas: tienen un propósito único y obvio.

+ +

Abramos src/App.js, ya que nuestro navegador nos pide que lo editemos. Este archivo contiene nuestro primer componente —App—, y algunas otras líneas de código:

+ +
import React from 'react';
+import logo from './logo.svg';
+import './App.css';
+
+function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Edit <code>src/App.js</code> and save to reload.
+        </p>
+        <a
+          className="App-link"
+          href="https://reactjs.org"
+          target="_blank"
+          rel="noopener noreferrer"
+        >
+          Learn React
+        </a>
+      </header>
+    </div>
+  );
+}
+export default App;
+ +

El archivo App.js se compone de tres partes principales: algunas declaraciones import en la parte superior, el componente App en el medio, y una declaración export en la parte inferior. La mayoría de los componentes de React siguen este patrón.

+ +

Declaraciones import

+ +

Las declaraciones import en la parte superior del archivo le permiten a App.js utilizar código que ha sido definido en otra parte. Revisemos estas declaraciones más detalladamente.

+ +
import React from 'react';
+import logo from './logo.svg';
+import './App.css';
+ +

La primera declaración importa la biblioteca React como tal. Dado que React convierte el JSX que escribimos en React.createElement(), todos los componentes de React deben importar el módulo React. Si omites este paso, tu aplicación producirá un error.

+ +

La segunda declaración importa un logotipo de './logo.svg'. Observa el uso de ./ al principio de la ruta y la extensión .svg al final — estos nos indican que el archivo es local y que no es un archivo JavaScript. De hecho, el archivo logo.svg reside en nuestra carpeta raíz.

+ +

No hace falta proveer una ruta o extensión al importar el módulo React, ya que este no es un archivo local. En cambio, aparece como una dependencia en nuestro archivo package.json. ¡Ten cuidado con esta distinción mientras trabajas en esta lección!

+ +

La tercera declaración importa el CSS relacionado con nuestro componente App. Observa que no hay nombre de variable ni de directiva from. Esta sintaxis de importación en particular no es propia de la sintaxis de módulos de JavaScript. Esta proviene de Webpack, la herramienta que create-react-app usa para agrupar todos nuestros archivos JavaScript y enviarlos al navegador.

+ +

El componente App

+ +

Después de las importaciones, tenemos una función llamada App. Mientras que una mayor parte de la comunidad JavaScript prefiere nombres tipo camel-case como helloWorld, los componentes de React usan nombres de variables tipo pascal-case, como HelloWorld, para dejar en claro que un determinado elemento JSX es un componente de React y no una etiqueta HTML normal. Si llegaras a cambiar el nombre de la función App por app, tu navegador te mostraría un error.

+ +

Vamos a darle un vistazo más detallado a App.

+ +
function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          Edit <code>src/App.js</code> and save to reload.
+        </p>
+        <a
+          className="App-link"
+          href="https://reactjs.org"
+          target="_blank"
+          rel="noopener noreferrer"
+        >
+          Learn React
+        </a>
+      </header>
+    </div>
+  );
+}
+ +

La función App devuelve una expresión JSX. Esta expresión define lo que tu navegador presenta en última instancia al DOM.

+ +

Algunos elementos de la expresión tienen atributos, los cuales se escriben igual que en HTML, siguiendo un patrón de atributo="valor". En la línea 3, la etiqueta de apertura <div> tiene un atributo className. Este es equivalente al atributo class de HTML, pues dado que JSX es JavaScript, no podemos usar la palabra class —la cual está reservada—, lo que significa que JavaScript ya la usa para un propósito específico y causaría problemas en nuestro código. Algunos otros atributos HTML también se escriben de manera diferente en JSX (de como se escriben en HTML), por el mismo tipo de razón. Los revisaremos a medida que nos crucemos con estos.

+ +

Tómate un momento para cambiar la etiqueta <p> en la línea 6 para que diga "¡Hola, mundo!", luego guarda los cambios. Notarás que este cambio se procesa inmediatamente en el servidor de desarrollo que se ejecuta en http://localhost:3000 en tu navegador. Ahora elimina la etiqueta <a> y guarda los cambios; el enlace "Learn React" habrá desaparecido.

+ +

Ahora, tu componente App debería lucir así:

+ +
function App() {
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          ¡Hola, mundo!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

Declaraciones export

+ +

En la parte inferior del archivo App.js, la declaración export default App hace que nuestro componente App esté disponible para otros módulos.

+ +

Explorando el index

+ +

Vamos a abrir el archivo src/index.js, ya que es en este donde el componente App está siendo utilizado. Este archivo es el punto de entrada para nuestra aplicación, e inicialmente luce así:

+ +
import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+import * as serviceWorker from './serviceWorker';
+
+ReactDOM.render(<App />, document.getElementById('root'));
+
+// If you want your app to work offline and load faster, you can change
+// unregister() to register() below. Note this comes with some pitfalls.
+// Learn more about service workers: https://bit.ly/CRA-PWA
+serviceWorker.unregister();
+ +

Al gual que App.js, el archivo comienza importando todos los módulos JS y otros activos que necesita para ejecutarse. src/index.css contiene estilos globales que se aplican a toda nuestra aplicación. Podemos ver que nuestro componente App también es importado acá; su importación es posible gracias a la declaración export en la parte inferior de App.js.

+ +

En la línea 7, se invoca la función ReactDOM.render() de React con dos argumentos:

+ + + +

Todo esto le indica a React que queremos renderizar nuestra aplicación React con el componente App como raíz, o primer componente.

+ +
+

Nota: En JSX, los componentes de React y los elementos HTML deben tener, obligatoriamente, barras diagonales de cierre. Escribir solo <App> o solo <img> provocará un error.

+
+ +

Los Service workers son interesantes piezas de código que ayudan al rendimiento de las aplicaciones y permiten que las funciones de tus aplicaciones web funcionen sin conexión, pero estas no están dentro del alcance de este artículo. Puedes eliminar la línea 5, así como las líneas 9 a 12.

+ +

Finalmente, tu archivo index.js debería verse así:

+ +
import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+
+ReactDOM.render(<App />, document.getElementById('root'));
+ +

Variables y props

+ +

A continuación, usaremos algunas de nuestras habilidades de JavaScript para lograr sentirnos un poco más cómodos editando componentes y trabajando con datos en React. Hablaremos sobre cómo se usan las variables dentro de JSX, e introduciremos props, que son una forma de pasar datos a un componente (al que luego se puede acceder usando variables).

+ +

Variables en JSX

+ +

De vuelta en App.js, enfoquémonos en la línea 9:

+ +
<img src={logo} className="App-logo" alt="logo" />
+ +

Aquí, el valor del atributo src de la etiqueta <img /> está entre llaves. Así es como JSX reconoce las variables. Al encontrarse con {logo}, React sabrá que nos referimos a la importación del logotipo en la línea 2 de nuestra aplicación, y luego recuperará el archivo del logo y lo renderizará.

+ +

Vamos a intentar crear una variable propia. Antes de la declaración return de App, agrega const subject = "React";. Tu componente App ahora debería verse así:

+ +
function App() {
+  const subject = "React";
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          ¡Hola, mundo!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

Cambia la línea 8, de manera que se use la variable subject en vez de la palabra "mundo", así:

+ +
function App() {
+  const subject = "React";
+  return (
+    <div className="App">
+      <header className="App-header">
+        <img src={logo} className="App-logo" alt="logo" />
+        <p>
+          ¡Hola, {subject}!
+        </p>
+      </header>
+    </div>
+  );
+}
+ +

Al guardar, tu navegador debería mostrar "¡Hola, React!" en vez de "¡Hola, mundo!"

+ +

Las variables son convenientes, pero la que acabamos de configurar no hace gran uso de las funciones de React. Es allí donde entran los props.

+ +

Props de componentes

+ +

Un prop es cualquier dato que se pasa a un componente de React. Los props se escriben dentro de las llamadas a los componentes y utilizan la misma sintaxis que los atributos HTML: prop="value". Abramos index.js y démosle a la llamada de nuestro <App/> su primer prop.

+ +

Agrega un prop de subject a la llamada del componente <App />, con un valor de Clarice. Al terminar, tu código debería verse similar a este:

+ +
ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));
+ +

Volviendo a App.js, vamos a revisar nuevamente la función App como tal, la cual se lee así (acortando la declaración return por razones de brevedad):

+ +
function App() {
+  const subject = "React";
+  return (
+    // return statement
+  );
+}
+ +

Cambia la declaración de la función App de manera que tome props como un parámetro, y elimina la constante subject. Al igual que cualquier otro parámetro de una función, puedes pasar props a console.log() para imprimirlos en la consola de tu navegador. Continúa, haciendo esto antes de la declaración return, así:

+ +
function App(props) {
+  console.log(props);
+  return (
+    // return statement
+  );
+}
+ +

Guarda tu archivo y revisa la consola JavaScript de tu navegador. Deberías ver registrado algo como esto:

+ +
Object { subject: "Clarice" }
+ +

La propiedad subject del objeto corresponde al prop subject que agregamos a la llamada de nuestro componente <App />, y la cadena Clarice corresponde a su valor. Los props de componentes en React siempre se recopilan en objetos de esta manera.

+ +

Ahora que subject es uno de nuestros props, usémoslo en App.js. Cambia la constante subject de manera que, en vez de definirla como la cadena React, estés leyendo el valor de props.subject. También puedes eliminar console.log(), si así lo quieres.

+ +
function App(props) {
+  const subject = props.subject;
+  return (
+    // return statement
+  );
+}
+ +

Una vez guardes, la aplicación debería darte la bienvenida con un "¡Hola, Clarice!". Si regresas a index.js, editas el valor de subject, y guardas, el texto cambiará.

+ +

Resumen

+ +

Esto nos lleva al final de nuestra introducción a React, la cual incluye cómo instalarlo de manera local, cómo crear una aplicación inicial, y cómo funcionan los conceptos básicos. En el próximo artículo comenzaremos a construir nuestra primera aplicación como tal: una lista de tareas pendientes. Sin embargo, antes de ello, recapitulemos algunas de las cosas que hemos aprendido.

+ +

En React:

+ + + +

{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/vue_primeros_pasos/index.html b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/vue_primeros_pasos/index.html new file mode 100644 index 0000000000..ea24ac2a81 --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/lado-del-cliente_javascript_frameworks/vue_primeros_pasos/index.html @@ -0,0 +1,294 @@ +--- +title: Primeros pasos con Vue +slug: >- + Learn/Herramientas_y_pruebas/Lado-del-cliente_JavaScript_frameworks/Vue_primeros_pasos +translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
+ +

Ahora vamos a introducir Vue, el tercero de nuestros frameworks. En este articulo vamos a ver un poco del background de Vue, aprenderemos cómo instalarlo y a crear un nuevo proyecto, estudiar la estructura de alto nivel de todo el proyecto y un componente individual, sabremos como correr el proyecto localmente, y tenerlo preparado para empezar a construir nuestro ejemplo.

+ + + + + + + + + + + + +
Pre-requisitos: +

Familiaridad con los motores de los lenguajes  HTML, CSS, y  JavaScript languages, conocimiento del terminal/command line.

+ +

Los componentes Vue son escritos como una combinacion de objectos Javascript que administran los datos de la app y una sintaxis de plantilla basada en HTML que se enlaza con la estructura DOM subyacente. Para la instalación, y para usar algunas de las caracteristicas mas avanzadas de Vue (como Componentes de archivos simples o renderizado de funciones), vas a necesitar un terminar con node + npm instalados.

+
Objetivo:Configurar un entorno de desarrollo local de Vue, crear una app de inicio y entender los principios de su funcionamiento.
+ +

Un Vue más claro

+ +

Vue es un framework moderno de Javascript que proveé facilidades muy utiles para el mejoramiento progresivo- al contrario de otros frameworks, puedes usar Vue para mejorar un HTML exstente. Esto permite usar Vue como un remplazo agregado para una libreria como JQuery.

+ +

Habiendo dicho esto, tambien puedes usar Vue para escribir completamente una aplicación de una sola página(SPAs).This allows you to create markup managed entirely by Vue, which can improve developer experience and performance when dealing with complex applications. It also allows you to take advantage of libraries for client-side routing and state management when you need to. Additionally, Vue takes a "middle ground" approach to tooling like client-side routing and state management. While the Vue core team maintains suggested libraries for these functions, they are not directly bundled into Vue. This allows you to select a different routing/state management library if they better fit your application.

+ +

In addition to allowing you to progressively integrate Vue into your applications, Vue also provides a progressive approach to writing markup. Like most frameworks, Vue lets you create reusable blocks of markup via components. Most of the time, Vue components are written using a special HTML template syntax. When you need more control than the HTML syntax allows, you can write JSX or plain JavaScript functions to define your  components.

+ +

As you work through this tutorial, you might want to keep the Vue guide and API documentation open in other tabs, so you can refer to them if you want more information on any sub topic.
+ For a good (but potentially biased) comparison between Vue and many of the other frameworks, see Vue Docs: Comparison with Other Frameworks.

+ +

Installation

+ +

To use Vue in an existing site, you can drop one of the following <script> elements onto a page. This allows you to start using Vue on existing sites, which is why Vue prides itself on being a progressive framework. This is a great option when migrating an existing project using a library like JQuery to Vue. With this method, you can use a lot of the core features of Vue, such as the attributes, custom components, and data-management.

+ + + +

However, this approach has some limitations. To build more complex apps, you’ll want to use the Vue NPM package. This will let you use advanced features of Vue and take advantage of bundlers like WebPack. To make building apps with Vue easier, there is a CLI to streamline the development process. To use the npm package & the CLI you will need:

+ +
    +
  1. Node.js 8.11+ installed.
  2. +
  3. npm or yarn.
  4. +
+ +
+

Note: If you don't have the above installed, find out more about installing npm and Node.js here.

+
+ +

To install the CLI, run the following command in your terminal:

+ +
npm install --global @vue/cli
+ +

Or if you'd prefer to use yarn:

+ +
yarn global add @vue/cli
+ +

Once installed, to initialize a new project you can then open a terminal in the directory you want to create the project in, and run vue create <project-name>. The CLI will then give you a list of project configurations you can use. There are a few preset ones, and you can make your own. These options let you configure things like TypeScript, linting, vue-router, testing, and more.

+ +

We’ll look at using this below.

+ +

Initializing a new project

+ +

To explore various features of Vue, we will be building up a sample todo list app. We'll begin by using the Vue CLI to create a new app framework to build our app into. Follow the steps below:

+ +
    +
  1. In terminal, cd to where you'd like to create your sample app, then run vue create moz-todo-vue.
  2. +
  3. Use the arrow keys and Enter to select the "Manually select features" option.
  4. +
  5. The first menu you’ll be presented with allows you to choose which features you want to include in your project. Make sure that "Babel" and "Linter / Formatter" are selected. If they are not, use the arrow keys and the space bar to toggle them on. Once they are selected, press Enter to proceed.
  6. +
  7. Next you’ll select a config for the linter / formatter. Navigate to "Eslint with error prevention only" and hit Enter again. This will help us catch common errors, but not be overly opinionated.
  8. +
  9. Next you are asked to configure what kind of automated linting we want. Select "Lint on save". This will check for errors when we save a file inside the project. Hit Enter to continue.
  10. +
  11. Now, you will select how we want your config files to be managed. "In dedicated config files" will put your config settings for things like ESLint into their own, dedicated files. The other option, "In package.json", will put all of your config settings into the app's package.json file. Select "In dedicated config files" and push Enter.
  12. +
  13. Finally, you are asked if you want to save this as a preset for future options. This is entirely up to you. If you like these settings over the existing presets and want to use them again, type y , otherwise type n.
  14. +
+ +

The CLI will now begin scaffolding out your project, and installing all of your dependencies.

+ +

If you've never run the Vue CLI before, you'll get one more question — you'll be asked to choose a package manager. You can use the arrow keys to select which one you prefer. The Vue CLI will default to this package manager from now on. If you need to use a different package manager after this, you can pass in a flag --packageManager=<package-manager>, when you run vue create.  So if you wanted to create the moz-todo-vue project with npm and you'd previously chosen yarn, you’d run vue create moz-todo-vue --packageManager=npm.

+ +
+

Note: We've not gone over all of the options here, but you can find more information on the CLI in the Vue docs.

+
+ +

Project structure

+ +

If everything went successfully, the CLI should have created a series of files and directories for your project. The most significant ones are as follows:

+ + + +
+

Note: Depending on the options you select when creating a new project, there might be other directories present (for example, if you choose a router, you will also have a views directory).

+
+ +

.vue files (single file components)

+ +

Like in many front-end frameworks, components are a central part of building apps in Vue. These components let you break a large application into discrete building blocks that can be created and managed separately, and transfer data between each other as required. These small blocks can help you reason about and test your code.

+ +

While some frameworks encourage you to separate your template, logic, and styling code into separate files, Vue takes the opposite approach. Using Single File Components, Vue lets you group your templates, corresponding script, and CSS all together in a single file ending in .vue. These files are processed by a JS build tool (such as Webpack), which means you can take advantage of build-time tooling in your project. This allows you to use tools like Babel, TypeScript, SCSS and more to create more sophisticated components.

+ +

As a bonus, projects created with the Vue CLI are configured to use .vue files with Webpack out of the box. In fact, if you look inside the src folder in the project we created with the CLI, you'll see your first .vue file: App.vue.

+ +

Let's explore this now.

+ +

App.vue

+ +

Open your App.vue file — you’ll see that it has three parts: <template>, <script>, and <style>, which contain the component’s template, scripting, and styling information. All Single File Components share this same basic structure.

+ +

<template> contains all the markup structure and display logic of your component. Your template can contain any valid HTML, as well as some Vue-specific syntax that we'll cover later.

+ +
+

Note: By setting the lang attribute on the <template> tag, you can use Pug template syntax instead of standard HTML — <template lang="pug">. We'll stick to standard HTML through this tutorial, but it is worth knowing that this is possible.

+
+ +

<script> contains all of the non-display logic of your component. Most importantly, your <script> tag needs to have a default exported JS object. This object is where you locally register components, define component inputs (props), handle local state, define methods, and more. Your build step will process this object and transform it (with your template) into a Vue component with a render() function.

+ +

In the case of App.vue, our default export sets the name of the component to app and registers the HelloWorld component by adding it into the components property. When you register a component in this way, you're registering it locally. Locally registered components can only be used inside the components that register them, so you need to import and register them in every component file that uses them. This can be useful for bundle splitting/tree shaking since not every page in your app necessarily needs every component.

+ +
import HelloWorld from './components/HelloWorld.vue';
+
+export default {
+  name: 'app',
+  components: {
+    //You can register components locally here.
+    HelloWorld
+  }
+};
+ +
+

Note: If you want to use TypeScript syntax, you need to set the lang attribute on the <script> tag to signify to the compiler that you're using TypeScript — <script lang="ts">.

+
+ +

<style> is where you write your CSS for the component. If you add a scoped attribute — <style scoped> — Vue will scope the styles to the contents of your SFC. This works similar to CSS-in-JS solutions, but allows you to just write plain CSS.

+ +
+

Note: If you select a CSS pre-processor when creating the project via the CLI, you can add a lang attribute to the <style> tag so that the contents can be processed by Webpack at build time. For example, <style lang="scss"> will allow you to use SCSS syntax in your styling information.

+
+ +

Running the app locally

+ +

The Vue CLI comes with a built-in development server. This allows you to run your app locally so you can test it easily without needing to configure a server yourself. The CLI adds a serve command to the project’s package.json file as an npm script, so you can easily run it.

+ +

In your terminal, try running npm run serve (or yarn serve if you prefer yarn). Your terminal should output something like the following:

+ +
INFO  Starting development server...
+98% after emitting CopyPlugin
+
+ DONE  Compiled successfully in 18121ms
+
+  App running at:
+  - Local:   <http://localhost:8080/>
+  - Network: <http://192.168.1.9:8080/>
+
+  Note that the development build is not optimized.
+  To create a production build, run npm run build.
+ +

If you navigate to the “local” address in a new browser tab (this should be something like http://localhost:8080 as stated above, but may vary based on your setup), you should see your app. Right now, it should contain a welcome message, a link to the Vue documentation, links to the plugins you added when you initialized the app with your CLI, and some other useful links to the Vue community and ecosystem.

+ +

default vue app render, with vue logo, welcome message, and some documentation links

+ +

Making a couple of changes

+ +

Let's make our first change to the app — we’ll delete the Vue logo. Open the App.vue file, and delete the <img> element from the template section:

+ +
<img alt="Vue logo" src="./assets/logo.png">
+ +

If your server is still running, you should see the logo removed from the rendered site almost instantly. Let’s also remove the HelloWorld component from our template.

+ +

First of all delete this line:

+ +
<HelloWorld msg="Welcome to Your Vue.js App"/>
+ +

If you save your App.vue file now, the rendered app will throw an error because we’ve registered the component but are not using it. We also need to remove the lines from inside the <script> element that import and register the component:

+ +

Delete these lines now:

+ +
import HelloWorld from './components/HelloWorld.vue'
+ +
components: {
+  HelloWorld
+}
+ +

Your rendered app should no longer show an error, just a blank page, as we currently have no visible content inside <template>.

+ +

Let’s add a new <h1> inside <div id="app">. Since we’re going to be creating a todo list app below, let's set our header text to "To-Do List". Add it like so:

+ +
<template>
+  <div id="app">
+    <h1>To-Do List</h1>
+  </div>
+</template>
+ +

App.vue will now show our heading, as you'd expect.

+ +

Summary

+ +

Let's leave this here for now. We've learnt about some of the ideas behind Vue, created some scaffolding for our example app to live inside, inspected it, and made a few preliminary changes.

+ +

With a basic introduction out of the way, we'll now go further and build up our sample app, a basic Todo list application that allows us to store a list of items, check them off when done, and filter the list by all, complete, and incomplete todos.

+ +

In the next article we'll build our first custom component, and look at some important concepts such as passing props into it and saving its data state.

+ +

{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

+ +

In this module

+ + diff --git a/files/es/learn/herramientas_y_pruebas/understanding_client-side_tools/index.html b/files/es/learn/herramientas_y_pruebas/understanding_client-side_tools/index.html new file mode 100644 index 0000000000..6221b0382f --- /dev/null +++ b/files/es/learn/herramientas_y_pruebas/understanding_client-side_tools/index.html @@ -0,0 +1,46 @@ +--- +title: Understanding client-side web development tools +slug: Learn/Herramientas_y_pruebas/Understanding_client-side_tools +tags: + - Aprender + - CSS + - Despliegue + - HTML + - Herramientas + - JavaScript + - Novatos + - Transformación + - client-side + - lado del cliente +translation_of: Learn/Tools_and_testing/Understanding_client-side_tools +--- +
{{LearnSidebar}}
+ +

Las herramientas del lado del cliente (client-side en inglés) pueden ser intimidantes, pero esta serie de artículos tiene como propósito ilustrar el propósito de algunos de los tipos de herramientas client-side, explicar las herramientas que puedes integrar, cómo instalarlas usando administradores de paquetes y cómo controlarlas usando la línea de comandos. Terminanos esta sección dando un ejemplo de cadena de herramientas para mostrarte cómo puedes ser más productivo

+ +

Inicia ahora con nuestra "Introducción a las herraminetas client-side"

+ +

Requisitos previos

+ +

Debes aprender el núcleo básico de los lenguajes HTML, CSS y JavaScript, antes de intentar usar las herramientas aquí descritas.

+ +
+

¿Quieres convertirte en un desarrollador front-end?

+ +

Tenemos un curso que incluye toda la información esencial que necesitas para lograr tu objetivo.

+Inicia ahora
+ +

Guías

+ +
+
1. Introducción a las herramientas client-side
+
En este artículo damos una introducción a las herramientas modernas de la web, los tipos de herramientas disponibles, donde te las puedes encontrar en el cliclo de desarrollo de aplicaciones web y como buscar ayuda con las herramientas individuales.
+
2. Introducción a la linea de comandos
+
En tu proceso de desarrollo seguramente vas a requeria correr algunos comandos en la terminal (o "línea de comandos"). Este artículo da una introducción a la terminal, los comandos básicos que vas a necesitar para utilizarla, cómo integrar diferentes comandos y cómo agregar tu propia interfaz de línea de comandos (command line interface - CLI en inglés).
+
3. Introducción al manejo de paquetes
+
En este artículo exploramos los sistemas de administración de paquetes en detalle para entender cómo los podemos usar en nuestros proyectos, ya sea para instalar dependencias a nuestro proyecto, descargar actualizaciones y mucho más.
+
4. Introduciendo una cadena de herramientas completa
+
En los últimos dos artículos en esta serie vamos a solidificar tu conocimiento de las herramientas para el desarrollo web construyendo una cadena de herramients. Iniciaremos configurando un ambiente de desarrollo y colocando herramentas de transformación para desplegar nuestra aplicación en Netlify. En este artículo introducimos un estudio de caso, configuramos nuestro ambiente de desarrollo y configuramos herramientas de transformación de código.
+
5. Desplegando nuestra aplicación
+
En el artículo final de esta serie, utilizamos nuestra cadena de herramientas que construimos en el artículo previo y la extendemos para desplegar nuestra aplicación muestra. Subimos nuestro código a GitHub, desplegamos usando Netlify e incluso te enseñamos a realizar una prueba en el proceso.
+
diff --git a/files/es/learn/html/como/index.html b/files/es/learn/html/como/index.html new file mode 100644 index 0000000000..095e5bc54e --- /dev/null +++ b/files/es/learn/html/como/index.html @@ -0,0 +1,141 @@ +--- +title: Solución de problemas comunes de HTML +slug: Learn/HTML/como +tags: + - CodificacióndeSecuenciadeComandos + - HTML +translation_of: Learn/HTML/Howto +--- +

{{LearnSidebar}}

+ +

Los siguientes enlaces brindan soluciones puntuales a los problemas más comunes a los que te enfrentarás a diario en HTML.

+ +
+
+

Estructura básica

+ +

La principal aplicación de HTML es la estructuración del documento. Si eres nuevo en HTML debes empezar aquí.

+ + + +

Semántica básica textos

+ +

HTML se especializa en suministrar información semántica del documento, así que HTML soluciona muchas dudas que puede tener sobre como transmitir su mensaje a través de un documento.

+ + +
+ +
+

Hipervínculos

+ +

Uno de las principales razones por las que HTML hace más fácil la navegación son los {{Glossary("hyperlink", "hipervínculos")}}, que pueden ser usados de diferentes formas:

+ + + +

Imágenes y multimedia

+ + + +

Scripts y estilización

+ +

HTML únicamente define la estructura del documento. Para solucionar los problemas de presentación usamos {{glossary("CSS")}}, o usamos scripts para hacer la página interactiva.

+ + + +

Contenido integrado

+ + +
+
+ +

Problemas avanzados o raros

+ +

Más allá de lo basico, HTML es muy rico y ofrece características avanzadas para solucionar problemas complejos. Estos artículos te ayudarán a abordar estos casos menos comunes:

+ +
+
+

Formularios

+ +

Los formularios son una estructura compleja en HTML para enviar datos desde una pagina web al servidor. Te animamos a que revises la guia completa. Aquí es por donde deberías empezar:

+ + + +

Información tabular

+ +

Alguna información, llamada datos tabulares, necesita ser organizada en tablas mediante filas y columnas. Siendo ésta una de las estructuras más complejas de HTML, no es fácil dominarla:

+ + + +

Representación de datos

+ + + +

Rendimiento

+ + +
+ +
+

Semántica avanzada de texto

+ + + +

Imágenes y multimedia avanzada

+ + + +

Internacionalización

+ +

HTML no es monolingüe. Éste proporciona herramientas para manejar problemas comunes de internacionalización.

+ + +
+
+ +

     

diff --git a/files/es/learn/html/como/usando_atributos_de_datos/index.html b/files/es/learn/html/como/usando_atributos_de_datos/index.html new file mode 100644 index 0000000000..7629974833 --- /dev/null +++ b/files/es/learn/html/como/usando_atributos_de_datos/index.html @@ -0,0 +1,75 @@ +--- +title: Uso de atributos de datos +slug: Learn/HTML/como/Usando_atributos_de_datos +translation_of: Learn/HTML/Howto/Use_data_attributes +--- +
{{LearnSidebar}}
+ +

HTML5 está diseñado de forma tal que sea fácil extender los datos asociados a un elemento en particular sin necesidad de que tengan un significado definido. Los atributos data-*  permiten almacenar información adicional sobre un elemento HTML cualquiera sin tener que recurrir a artilugios tales como la utilización de atributos no estándar, propiedades adicionales en el DOM o {{domxref("Node.setUserData()")}}.

+ +

Sintaxis HTML

+ +

La sintáxis es simple. Un atributo cualquiera cuyo nombre comience con data-es un atributo de datos. Supongamos que tenemos un artículo y deseamos almacenar información adicional que no tiene ninguna representación visual. En ese caso, alcanza con que hagamos uso de los atributos data:

+ +
<article
+  id="electriccars"
+  data-columns="3"
+  data-index-number="12314"
+  data-parent="cars">
+...
+</article>
+ +

Acceso a través de JavaScript

+ +

Leer los valores de estos atributos en JavaScript también es muy sencillo. Puede usar {{domxref("Element.getAttribute", "getAttribute()")}} con su nombre HTML completo para leerlos, pero el estándar define una forma más simple: un {{domxref("DOMStringMap")}} puede leer a través de una propiedad {{domxref("HTMLElement.dataset", "dataset")}}.

+ +

Para obtener un atributo data a través del dataset del objeto, obtenga la propiedad por la parte del nombre del atributo despues de data- (tenga en cuenta que los guiones son convertidos en camelCase).

+ +
var article = document.getElementById('electriccars');
+
+article.dataset.columns // "3"
+article.dataset.indexNumber // "12314"
+article.dataset.parent // "cars"
+ +

Cada propiedad es una cadena y se puede leer y escribir. En el caso anterior, establecer article.dataset.columns = 5 cambiaría ese atributo a "5".

+ +

Acceso a través de CSS

+ +

Tenga en cuenta que, debido a que los atributos de datos son atributos simples de HTML, incluso puede acceder a ellos desde CSS. Por ejemplo, para mostrar los data-parent en el artículo, puede usar el contenido generado en CSS con la función {{cssxref("attr")}}:

+ +
article::before {
+  content: attr(data-parent);
+}
+ +

También puede usar los selectores de atributos en CSS para cambiar los estilos de acuerdo a las priopiedades de datos:

+ +
article[data-columns='3'] {
+  width: 400px;
+}
+article[data-columns='4'] {
+  width: 600px;
+}
+ +

Puede ver todo esto trabajando junto en este ejemplo de JSBin.

+ +

Los atributos de datos también se pueden almacenar para que contengan información que cambia constantemente, como los puntajes en un juego. Usando los selectores de CSS y el acceso a JavaScript aquí, esto le permite crear algunos efectos ingeniosos sin tener que escribir sus propias rutinas de visualización. Consulte este screencast para ver un ejemplo utilizando contenido generado y transacciones CSS (Ejemplo JSBin).

+ +

Los valores de datos son cadenas de caracteres. Los valores numéricos deben ser citados en el selector para que el estilo surta efecto.

+ +

Problemas

+ +

No almacene el contenido que debería ser visible y accesible en los atributos de datos, ya que las tecnologías de asistencia, no pueden acceder a ellos. Ademas, los rastreadores de búsqueda no pueden indexar los valores de los atributos de datos.

+ +

Los principales problemas a considerar son el soporte y rendimiento en Internet Explorer. Internet Explorer 11 y superiores, proporcionan soporte para el estándar, pero todas las versiones anteriores no son compatibles con dataset. Para admitir IE 10 e inferiores, debe acceder a los atributos de datos con {{domxref("Element.getAttribute", "getAttribute()")}} en su lugar. Ademas, el rendimiento de lectura de los atributos de datos en comparación con el almacenamiento de estos datos en un objeto JS normal es deficiente.

+ +

Dicho esto, sin embargo, para metadatos asociados a elementos personalizados, son una gran solución.

+ +

En Firefox 49.0.2 (y quizás versiones anteriores), los atributos de datos que exceden los 1022 caracteres no serán leídos por Javascript (EcmaScript 4).

+ +

Ver también

+ + diff --git a/files/es/learn/html/forms/como_crear_widgets_de_formularios_personalizados/index.html b/files/es/learn/html/forms/como_crear_widgets_de_formularios_personalizados/index.html new file mode 100644 index 0000000000..73ae6e6590 --- /dev/null +++ b/files/es/learn/html/forms/como_crear_widgets_de_formularios_personalizados/index.html @@ -0,0 +1,786 @@ +--- +title: Cómo crear widgets de formularios personalizados +slug: Learn/HTML/Forms/como_crear_widgets_de_formularios_personalizados +translation_of: Learn/Forms/How_to_build_custom_form_controls +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}
+ +

Hay muchos casos donde los widgets de formularios HTML disponibles simplemente no son suficientes. si desea establecer un estilo avanzado en algunos widgets como el elemento {{HTMLElement("select")}} o si desea proporcionar comportamientos personalizados, no tiene más opción que crear sus propios widgets.

+ +

En este aartículo, veremos cómo construir dicho widget. Para ello, trabajaremos con un ejemplo: Reconstruir el elemento {{HTMLElement("select")}}.

+ +
+

Nota: Nos enfocaremos en construir los widgets, no en cómo hacer que el código sea genérico y reutilizable; eso implicaría algún código JavaScript no trivial y manipulación del DOM en un contexto desconocido, y eso está fuera del alcance de este artículo.

+
+ +

Diseño, estructura, y semántica

+ +

Antes de crear un widget personalizado, debería iniciar por averiguar exactamente qué es lo que desea. Esto le ahorarrá tiempo considerable. En particular, es importante definir claramente todos los estados de su widget. Para hacer esto, es bueno comenzar con un widget existente, cuyos estados y comportamientos son bien conocidos, por lo que simplemente puede imitarlos tanto como sea posible.

+ +

En nuestro ejemplo, reconstruiremos el elemento {{HTMLElement("select")}}. Este es el resultado que queremos lograr:

+ +

The three states of a select box

+ +

Esta captura de pantall muestra los tres estados principales de nuestro widget: el estado normal (a la izquiera); el estado activo (en el centro) y el estado abierto (a la derecha).

+ +

En términos de comportamiento, queremos que nuestro widget sea utilizable tanto con un ratón como con un teclado, al igual que cualquier widget nativo. Comencemos por definir cómo el widget llega a cada estado:

+ +
+
El widget está en su estado normal cuando:
+
+
    +
  • La página carga
  • +
  • El widget estaba activo y el usuario hace clic en cualquier lugar fuera del widget
  • +
  • El widget estaba activo y el usuario mueve el foco a otro widget usando el teclado
  • +
+ +
+

Nota: Mover el foco al rededor de la página generalmente se hace presionando la tecla de tabulación, pero este no es el estándar en todas partes. Por ejemplo, el ciclo a través de enlaces en una página se realiza en Safari de forma predeterminada usando la combinación combinación Opction+Tab.

+
+
+
El widget está en su estado activo cuando:
+
+
    +
  • El usuario hace clic en él
  • +
  • El usuario presiona la tecla tab y obtiene foco
  • +
  • El widget estaba en su estado abierto y el usuario hace clic en el widget.
  • +
+
+
El widget está en su estado abierto cuando:
+
+
    +
  • El widget está en cualquier otro estado diferente a abierto y el usuario hace clic en él.
  • +
+
+
+ +

Una vez que sabemos cómo cambiar los estados, es importante definir cómo cambiar el valor del widget:

+ +
+
El valor cambia cuando:
+
+
    +
  • El usuario hace clic en una opción cuando el widget está en estado abierto
  • +
  • El usuario pulsa las teclas de flecha hacia arriba o hacia abajocuando el widget está en estado activo
  • +
+
+
+ +

Finalmente, definamos cómo se comportarán las opciones del widget:

+ + + +

Para los fines de nuestro ejemplo, nos detendremos con eso; sin embargo, si eres un lector cuidadoso, notarás que faltan algunos comportamientos. Por ejemplo, ¿qué crees que sucederá si el usuario pulsa la tecla de tabulación mientras el widget está en estado abierto? La respuesta es ... nada. OK, el comportamiento correcto parece obvio, pero el hecho es que, como no está definido en nuestras especificaciones, es muy fácil pasar por alto este comportamiento. Esto es especialmente cierto en un entorno de equipo cuando las personas que diseñan el comportamiento del widget son diferentes de las que lo implementan.

+ +

Otro ejemplo divertido: ¿qué pasará si el usuario pulsa las teclas de flecha hacia arriba o hacia abajo mientras el widget está en estado abierto? Este es un poco más complicado. Si considera que el estado activo y el estado abierto son completamente diferentes, la respuesta es nuevamente "no pasará nada" porque no definimos ninguna interacción de teclado para el estado abierto. Por otro lado, si considera que el estado activo y el estado abierto se superponen un poco, el valor puede cambiar pero la opción definitivamente no se resaltará en consecuencia, una vez más porque no definimos ninguna interacción del teclado sobre las opciones cuando el widget es en su estado abierto (solo hemos definido lo que debería suceder cuando se abre el widget, pero nada después de eso).

+ +

En nuestro ejemplo, las especificaciones faltantes son obvias, así que las manejaremos, pero puede ser un problema real en widgets nuevos y exóticos, para los cuales nadie tiene la menor idea de cuál es el comportamiento correcto. Por lo tanto, siempre es bueno pasar tiempo en esta etapa de diseño, porque si defines un comportamiento deficiente u olvidas definir uno, será muy difícil redefinirlo una vez que los usuarios se hayan acostumbrado. Si tiene dudas, solicite las opiniones de los demás y, si tiene el presupuesto para ello, no dude en realizar las pruebas de usuario. Este proceso se llama Diseño UX. Si desea obtener más información sobre este tema, debe consultar los siguientes recursos útiles:

+ + + +
+

Nota: Ademas, en la mayoría de los sistemas hay una forma de abrir el elemento {{HTMLElement("select")}} para ver todas las opciones disponibles (esto es lo mismo que hacer clic en el elemento {{HTMLElement("select")}} con un ratón). Esto se logra con Alt+Flecha abajo en Windows y no fué implementado en nuestro ejemplo —pero sería facil hacerlo, ya que el mecanismo ya se implementó para el evento clic.

+
+ +

Definiendo la estructura y semántica HTML

+ +

Ahora que se ha decidido la funcionalidad básica del widget, es hora de comenzar a construir nuestro widget. El primer paso es definir su estructura HTML y darle una semántica básica. Esto es lo que necesitamos para reconstruir un elemento {{HTMLElement("select")}}:

+ +
<!-- Este es nuestro contenedor principal para nuestro widget.
+     El atributo tabindex es lo que permite al usuario enforcar el widget.
+     Veremos más adelante que es mejor configurarlo a través de JavaScript. -->
+<div class="select" tabindex="0">
+
+  <!-- Este contenedor será usado para mostrar el valor actual del widget -->
+  <span class="value">Cherry</span>
+
+  <!-- Este contenedor contedrá todas las opciones disponibles para nuestro widget.
+       Como es una lista, tiene sentido usar el elemento ul. -->
+  <ul class="optList">
+    <!-- Cada opción solo contiene el valor que se mostrará, veremos más tarde
+         cómo manejar el valor real que será enviado con el formulario de datos -->
+    <li class="option">Cherry</li>
+    <li class="option">Lemon</li>
+    <li class="option">Banana</li>
+    <li class="option">Strawberry</li>
+    <li class="option">Apple</li>
+  </ul>
+
+</div>
+ +

Tenga en cuanta el uso de nombres de clases; estos identifican cada parte relevante independientemente de los elementos HTML subyacentes reales utilizados. Esto es importante para garantizar que no vinculamos nuestro CSS y JavaScript a una estructura HTML sólida, de modo que podamos realizar cambios despues en la implementación sin romper el código que usa el widget. Pro ejemplo, si desea implementar el equivalente del elemento {{HTMLElement("optgroup")}}.

+ +

Creating the look and feel using CSS

+ +

Now that we have a structure, we can start designing our widget. The whole point of building this custom widget is to be able to style this widget exactly as we want. To that end, we will split our CSS work into two parts: the first part will be the CSS rules absolutely necessary to have our widget behave like a {{HTMLElement("select")}} element, and the second part will consist of the fancy styles used to make it look the way we want.

+ +

Required styles

+ +

The required styles are those necessary to handle the three states of our widget.

+ +
.select {
+  /* This will create a positioning context for the list of options */
+  position: relative;
+
+  /* This will make our widget become part of the text flow and sizable at the same time */
+  display : inline-block;
+}
+ +

We need an extra class active to define the look and feel of our widget when it is in its active state. Because our widget is focusable, we double this custom style with the {{cssxref(":focus")}} pseudo-class in order to be sure they will behave the same.

+ +
.select.active,
+.select:focus {
+  outline: none;
+
+  /* This box-shadow property is not exactly required, however it's so important to be sure
+     the active state is visible that we use it as a default value, feel free to override it. */
+  box-shadow: 0 0 3px 1px #227755;
+}
+ +

Now, let's handle the list of options:

+ +
/* The .select selector here is syntactic sugar to be sure the classes we define are
+   the ones inside our widget. */
+.select .optList {
+  /* This will make sure our list of options will be displayed below the value
+     and out of the HTML flow */
+  position : absolute;
+  top      : 100%;
+  left     : 0;
+}
+ +

We need an extra class to handle when the list of options is hidden. This is necessary in order to manage the differences between the active state and the open state that do not exactly match.

+ +
.select .optList.hidden {
+  /* This is a simple way to hide the list in an accessible way,
+     we will talk more about accessibility in the end */
+  max-height: 0;
+  visibility: hidden;
+}
+ +

Beautification

+ +

So now that we have the basic functionality in place, the fun can start. The following is just an example of what is possible, and will match the screenshot at the beginning of this article. However, you should feel free to experiment and see what you can come up with.

+ +
.select {
+  /* All sizes will be expressed with the em value for accessibility reasons
+     (to make sure the widget remains resizable if the user uses the
+     browser's zoom in a text-only mode). The computations are made
+     assuming 1em == 16px which is the default value in most browsers.
+     If you are lost with px to em conversion, try http://riddle.pl/emcalc/ */
+  font-size   : 0.625em; /* this (10px) is the new font size context for em value in this context */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  /* We need extra room for the down arrow we will add */
+  padding : .1em 2.5em .2em .5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : .2em solid #000; /* 2px */
+  border-radius : .4em; /* 4px */
+  box-shadow    : 0 .1em .2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  /* The first declaration is for browsers that do not support linear gradients.
+     The second declaration is because WebKit based browsers haven't unprefixed it yet.
+     If you want to support legacy browsers, try http://www.colorzilla.com/gradient-editor/ */
+  background : #F0F0F0;
+  background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
+  background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0);
+}
+
+.select .value {
+  /* Because the value can be wider than our widget, we have to make sure it will not
+     change the widget's width */
+  display  : inline-block;
+  width    : 100%;
+  overflow : hidden;
+
+  vertical-align: top;
+
+  /* And if the content overflows, it's better to have a nice ellipsis. */
+  white-space  : nowrap;
+  text-overflow: ellipsis;
+}
+ +

We don't need an extra element to design the down arrow; instead, we're using the {{cssxref(":after")}} pseudo-element. However, it could also be implemented using a simple background image on the select class.

+ +
.select:after {
+  content : "▼"; /* We use the unicode caracter U+25BC; see http://www.utf8-chartable.de */
+  position: absolute;
+  z-index : 1; /* This will be important to keep the arrow from overlapping the list of options */
+  top     : 0;
+  right   : 0;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  height  : 100%;
+  width   : 2em;  /* 20px */
+  padding-top : .1em; /* 1px */
+
+  border-left  : .2em solid #000; /* 2px */
+  border-radius: 0 .1em .1em 0;  /* 0 1px 1px 0 */
+
+  background-color : #000;
+  color : #FFF;
+  text-align : center;
+}
+ +

Next, let's style the list of options:

+ +
.select .optList {
+  z-index : 2; /* We explicitly said the list of options will always overlap the down arrow */
+
+  /* this will reset the default style of the ul element */
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  /* This will ensure that even if the values are smaller than the widget,
+     the list of options will be as large as the widget itself */
+  min-width : 100%;
+
+  /* In case the list is too long, its content will overflow vertically
+     (which will add a vertical scrollbar automatically) but never horizontally
+     (because we haven't set a width, the list will adjust its width automatically.
+     If it can't, the content will be truncated) */
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+
+  border: .2em solid #000; /* 2px */
+  border-top-width : .1em; /* 1px */
+  border-radius: 0 0 .4em .4em; /* 0 0 4px 4px */
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4); /* 0 2px 4px */
+  background: #f0f0f0;
+}
+ +

For the options, we need to add a highlight class to be able to identify the value the user will pick (or has picked).

+ +
.select .option {
+  padding: .2em .3em; /* 2px 3px */
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

So here's the result with our three states:

+ + + + + + + + + + + + + + + + + + + +
Basic stateActive stateOpen state
{{EmbedLiveSample("Basic_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Active_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Open_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}
Check out the source code
+ +

Bring your widget to life with JavaScript

+ +

Now that our design and structure are ready, we can write the JavaScript code to make the widget actually work.

+ +
+

Warning: The following code is educational and should not be used as-is. Among many things, as we'll see, it is not future-proof and it will not work on legacy browsers. It also has redundant parts that should be optimized in production code.

+
+ +
+

Note: Creating reusable widgets is something that can be a bit tricky. The W3C Web Component draft is one of the answers to this specific issue. The X-Tag project is a test implementation of this specification; we encourage you to take a look at it.

+
+ +

Why isn't it working?

+ +

Before we start, it's important to remember something very important about JavaScript: inside a browser, it's an unreliable technology. When you are building custom widgets, you'll have to rely on JavaScript because it's a necessary thread to tie everything together. However, there are many cases in which JavaScript isn't able to run in the browser:

+ + + +

Because of these risks, it's really important to seriously consider what will happen if JavaScript isn't working. Dealing in detail with this issue is out of the scope of this article because it's closely linked to how you want to make your script generic and reusable, but we'll consider the basics of this in our example.

+ +

In our example, if our JavaScript code isn't running, we'll fall back to displaying a standard {{HTMLElement("select")}} element. To achieve this, we need two things.

+ +

First, we need to add a regular {{HTMLElement("select")}} element before each use of our custom widget. This is actually also required in order to be able to send data from our custom widget along with the rest of our form data; more about this later.

+ +
<body class="no-widget">
+  <form>
+    <select name="myFruit">
+      <option>Cherry</option>
+      <option>Lemon</option>
+      <option>Banana</option>
+      <option>Strawberry</option>
+      <option>Apple</option>
+    </select>
+
+    <div class="select">
+      <span class="value">Cherry</span>
+      <ul class="optList hidden">
+        <li class="option">Cherry</li>
+        <li class="option">Lemon</li>
+        <li class="option">Banana</li>
+        <li class="option">Strawberry</li>
+        <li class="option">Apple</li>
+      </ul>
+    </div>
+  </form>
+
+</body>
+ +

Second, we need two new classes to let us hide the unneeded element (that is, the "real" {{HTMLElement("select")}} element if our script isn't running, or the custom widget if it is running). Note that by default, our HTML code hides our custom widget.

+ +
.widget select,
+.no-widget .select {
+  /* This CSS selector basically says:
+     - either we have set the body class to "widget" and thus we hide the actual {{HTMLElement("select")}} element
+     - or we have not changed the body class, therefore the body class is still "no-widget",
+       so the elements whose class is "select" must be hidden */
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+ +

Now we just need a JavaScript switch to determine if the script is running or not. This switch is very simple: if at page load time our script is running, it will remove the no-widget class and add the widget class, thereby swapping the visibility of the {{HTMLElement("select")}} element and of the custom widget.

+ +
window.addEventListener("load", function () {
+  document.body.classList.remove("no-widget");
+  document.body.classList.add("widget");
+});
+ + + + + + + + + + + + + + + + + +
Without JSWith JS
{{EmbedLiveSample("No_JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}{{EmbedLiveSample("JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}
Check out the source code
+ +
+

Note: If you really want to make your code generic and reusable, instead of doing a class switch it's far better to just add the widget class to hide the {{HTMLElement("select")}} elements, and to dynamically add the DOM tree representing the custom widget after every {{HTMLElement("select")}} element in the page.

+
+ +

Making the job easier

+ +

In the code we are about to build, we will use the standard DOM API to do all the work we need. However, although DOM API support has gotten much better in browsers, there are always issues with legacy browsers (especially with good old Internet Explorer).

+ +

If you want to avoid trouble with legacy browsers, there are two ways to do so: using a dedicated framework such as jQuery, $dom, prototype, Dojo, YUI, or the like, or by polyfilling the missing feature you want to use (which can easily be done through conditional loading, with the yepnope library for example).

+ +

The features we plan to use are the following (ordered from the riskiest to the safest):

+ +
    +
  1. {{domxref("element.classList","classList")}}
  2. +
  3. {{domxref("EventTarget.addEventListener","addEventListener")}}
  4. +
  5. forEach (This is not DOM but modern JavaScript)
  6. +
  7. {{domxref("element.querySelector","querySelector")}} and {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. +
+ +

Beyond the availability of those specific features, there is still one issue remaining before starting. The object returned by the {{domxref("element.querySelectorAll","querySelectorAll()")}} function is a {{domxref("NodeList")}} rather than an Array. This is important because Array objects support the forEach function, but {{domxref("NodeList")}} doesn't. Because {{domxref("NodeList")}} really looks like an Array and because forEach is so convenient to use, we can easily add the support of forEach to {{domxref("NodeList")}} in order to make our life easier, like so:

+ +
NodeList.prototype.forEach = function (callback) {
+  Array.prototype.forEach.call(this, callback);
+}
+ +

We weren't kidding when we said it's easy to do.

+ +

Building event callbacks

+ +

The ground is ready, we can now start to define all the functions that will be used each time the user interacts with our widget.

+ +
// This function will be used each time we want to deactivate a custom widget
+// It takes one parameter
+// select : the DOM node with the `select` class to deactivate
+function deactivateSelect(select) {
+
+  // If the widget is not active there is nothing to do
+  if (!select.classList.contains('active')) return;
+
+  // We need to get the list of options for the custom widget
+  var optList = select.querySelector('.optList');
+
+  // We close the list of option
+  optList.classList.add('hidden');
+
+  // and we deactivate the custom widget itself
+  select.classList.remove('active');
+}
+
+// This function will be used each time the user wants to (de)activate the widget
+// It takes two parameters:
+// select : the DOM node with the `select` class to activate
+// selectList : the list of all the DOM nodes with the `select` class
+function activeSelect(select, selectList) {
+
+  // If the widget is already active there is nothing to do
+  if (select.classList.contains('active')) return;
+
+  // We have to turn off the active state on all custom widgets
+  // Because the deactivateSelect function fulfill all the requirement of the
+  // forEach callback function, we use it directly without using an intermediate
+  // anonymous function.
+  selectList.forEach(deactivateSelect);
+
+  // And we turn on the active state for this specific widget
+  select.classList.add('active');
+}
+
+// This function will be used each time the user wants to open/closed the list of options
+// It takes one parameter:
+// select : the DOM node with the list to toggle
+function toggleOptList(select) {
+
+  // The list is kept from the widget
+  var optList = select.querySelector('.optList');
+
+  // We change the class of the list to show/hide it
+  optList.classList.toggle('hidden');
+}
+
+// This function will be used each time we need to highlight an option
+// It takes two parameters:
+// select : the DOM node with the `select` class containing the option to highlight
+// option : the DOM node with the `option` class to highlight
+function highlightOption(select, option) {
+
+  // We get the list of all option available for our custom select element
+  var optionList = select.querySelectorAll('.option');
+
+  // We remove the highlight from all options
+  optionList.forEach(function (other) {
+    other.classList.remove('highlight');
+  });
+
+  // We highlight the right option
+  option.classList.add('highlight');
+};
+ +

That's all you need in order to handle the various states of the custom widget.

+ +

Next, we bind these functions to the appropriate events:

+ +
// We handle the event binding when the document is loaded.
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  // Each custom widget needs to be initialized
+  selectList.forEach(function (select) {
+
+    // as well as all its `option` elements
+    var optionList = select.querySelectorAll('.option');
+
+    // Each time a user hovers their mouse over an option, we highlight the given option
+    optionList.forEach(function (option) {
+      option.addEventListener('mouseover', function () {
+        // Note: the `select` and `option` variable are closures
+        // available in the scope of our function call.
+        highlightOption(select, option);
+      });
+    });
+
+    // Each times the user click on a custom select element
+    select.addEventListener('click', function (event) {
+      // Note: the `select` variable is a closure
+      // available in the scope of our function call.
+
+      // We toggle the visibility of the list of options
+      toggleOptList(select);
+    });
+
+    // In case the widget gain focus
+    // The widget gains the focus each time the user clicks on it or each time
+    // they use the tabulation key to access the widget
+    select.addEventListener('focus', function (event) {
+      // Note: the `select` and `selectList` variable are closures
+      // available in the scope of our function call.
+
+      // We activate the widget
+      activeSelect(select, selectList);
+    });
+
+    // In case the widget loose focus
+    select.addEventListener('blur', function (event) {
+      // Note: the `select` variable is a closure
+      // available in the scope of our function call.
+
+      // We deactivate the widget
+      deactivateSelect(select);
+    });
+  });
+});
+ +

At that point, our widget will change state according to our design, but its value doesn't get updated yet. We'll handle that next.

+ + + + + + + + + + + + + + + +
Live example
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}
Check out the source code
+ +

Handling the widget's value

+ +

Now that our widget is working, we have to add code to update its value according to user input and make it possible to send the value along with form data.

+ +

The easiest way to do this is to use a native widget under the hood. Such a widget will keep track of the value with all the built-in controls provided by the browser, and the value will be sent as usual when a form is submitted. There's no point in reinventing the wheel when we can have all this done for us.

+ +

As seen previously, we already use a native select widget as a fallback for accessibility reasons; we can simply synchronize its value with that of our custom widget:

+ +
// This function updates the displayed value and synchronizes it with the native widget.
+// It takes two parameters:
+// select : the DOM node with the class `select` containing the value to update
+// index  : the index of the value to be selected
+function updateValue(select, index) {
+  // We need to get the native widget for the given custom widget
+  // In our example, that native widget is a sibling of the custom widget
+  var nativeWidget = select.previousElementSibling;
+
+  // We also need  to get the value placeholder of our custom widget
+  var value = select.querySelector('.value');
+
+  // And we need the whole list of options
+  var optionList = select.querySelectorAll('.option');
+
+  // We set the selected index to the index of our choice
+  nativeWidget.selectedIndex = index;
+
+  // We update the value placeholder accordingly
+  value.innerHTML = optionList[index].innerHTML;
+
+  // And we highlight the corresponding option of our custom widget
+  highlightOption(select, optionList[index]);
+};
+
+// This function returns the current selected index in the native widget
+// It takes one parameter:
+// select : the DOM node with the class `select` related to the native widget
+function getIndex(select) {
+  // We need to access the native widget for the given custom widget
+  // In our example, that native widget is a sibling of the custom widget
+  var nativeWidget = select.previousElementSibling;
+
+  return nativeWidget.selectedIndex;
+};
+ +

With these two functions, we can bind the native widgets to the custom ones:

+ +
// We handle event binding when the document is loaded.
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  // Each custom widget needs to be initialized
+  selectList.forEach(function (select) {
+    var optionList = select.querySelectorAll('.option'),
+        selectedIndex = getIndex(select);
+
+    // We make our custom widget focusable
+    select.tabIndex = 0;
+
+    // We make the native widget no longer focusable
+    select.previousElementSibling.tabIndex = -1;
+
+    // We make sure that the default selected value is correctly displayed
+    updateValue(select, selectedIndex);
+
+    // Each time a user clicks on an option, we update the value accordingly
+    optionList.forEach(function (option, index) {
+      option.addEventListener('click', function (event) {
+        updateValue(select, index);
+      });
+    });
+
+    // Each time a user uses their keyboard on a focused widget, we update the value accordingly
+    select.addEventListener('keyup', function (event) {
+      var length = optionList.length,
+          index  = getIndex(select);
+
+      // When the user hits the down arrow, we jump to the next option
+      if (event.keyCode === 40 && index < length - 1) { index++; }
+
+      // When the user hits the up arrow, we jump to the previous option
+      if (event.keyCode === 38 && index > 0) { index--; }
+
+      updateValue(select, index);
+    });
+  });
+});
+ +

In the code above, it's worth noting the use of the tabIndex property. Using this property is necessary to ensure that the native widget will never gain focus, and to make sure that our custom widget gains focus when the user uses his keyboard or his mouse.

+ +

With that, we're done! Here's the result:

+ + + + + + + + + + + + + + + +
Live example
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}
Check out the source code
+ +

But wait a second, are we really done?

+ +

Make it accessible

+ +

We have built something that works and though we're far from a fully-featured select box, it works nicely. But what we've done is nothing more than fiddle with the DOM. It has no real semantics, and even though it looks like a select box, from the browser's point of view it isn't one, so assistive technologies won't be able to understand it's a select box. In short, this pretty new select box isn't accessible!

+ +

Fortunately, there is a solution and it's called ARIA. ARIA stands for "Accessible Rich Internet Application", and it's a W3C specification specifically designed for what we are doing here: making web applications and custom widgets accessible. It's basically a set of attributes that extend HTML so that we can better describe roles, states and properties as though the element we've just devised was the native element it tries to pass for. Using these attributes is dead simple, so let's do it.

+ +

The role attribute

+ +

The key attribute used by ARIA is the role attribute. The role attribute accepts a value that defines what an element is used for. Each role defines its own requirements and behaviors. In our example, we will use the listbox role. It's a "composite role", which means elements with that role expect to have children, each with a specific role (in this case, at least one child with the option role).

+ +

It's also worth noting that ARIA defines roles that are applied by default to standard HTML markup. For example, the {{HTMLElement("table")}} element matches the role grid, and the {{HTMLElement("ul")}} element matches the role list. Because we use a {{HTMLElement("ul")}} element, we want to make sure the listbox role of our widget will supersede the list role of the {{HTMLElement("ul")}} element. To that end, we will use the role presentation. This role is designed to let us indicate that an element has no special meaning, and is used solely to present information. We will apply it to our {{HTMLElement("ul")}} element.

+ +

To support the listbox role, we just have to update our HTML like this:

+ +
<!-- We add the role="listbox" attribute to our top element -->
+<div class="select" role="listbox">
+  <span class="value">Cherry</span>
+  <!-- We also add the role="presentation" to the ul element -->
+  <ul class="optList" role="presentation">
+    <!-- And we add the role="option" attribute to all the li elements -->
+    <li role="option" class="option">Cherry</li>
+    <li role="option" class="option">Lemon</li>
+    <li role="option" class="option">Banana</li>
+    <li role="option" class="option">Strawberry</li>
+    <li role="option" class="option">Apple</li>
+  </ul>
+</div>
+ +
+

Note: Including both the role attribute and a class attribute is only necessary if you want to support legacy browsers that do not support the CSS attribute selectors.

+
+ +

The aria-selected attribute

+ +

Using the role attribute is not enough. ARIA also provides many states and property attributes. The more and better you use them, the better your widget will be understood by assistive technologies. In our case, we will limit our usage to one attribute: aria-selected.

+ +

The aria-selected attribute is used to mark which option is currently selected; this lets assistive technologies inform the user what the current selection is. We will use it dynamically with JavaScript to mark the selected option each time the user chooses one. To that end, we need to revise our updateValue() function:

+ +
function updateValue(select, index) {
+  var nativeWidget = select.previousElementSibling;
+  var value = select.querySelector('.value');
+  var optionList = select.querySelectorAll('.option');
+
+  // We make sure that all the options are not selected
+  optionList.forEach(function (other) {
+    other.setAttribute('aria-selected', 'false');
+  });
+
+  // We make sure the chosen option is selected
+  optionList[index].setAttribute('aria-selected', 'true');
+
+  nativeWidget.selectedIndex = index;
+  value.innerHTML = optionList[index].innerHTML;
+  highlightOption(select, optionList[index]);
+};
+ +

Here is the final result of all these changes (you'll get a better feel for this by trying it with an assistive technology such as NVDA or VoiceOver):

+ + + + + + + + + + + + + + + +
Live example
{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}
Check out the final source code
+ +

Conclusion

+ +

We have seen all the basics of building a custom form widget, but as you can see it's not trivial to do, and often it's better and easier to rely on third-party libraries instead of coding them from scratch yourself (unless, of course, your goal is to build such a library).

+ +

Here are a few libraries you should consider before coding your own:

+ + + +

If you want to move forward, the code in this example needs some improvement before it becomes generic and reusable. This is an exercise you can try to perform. Two hints to help you in this: the first argument for all our functions is the same, which means those functions need the same context. Building an object to share that context would be wise. Also, you need to make it feature-proof; that is, it needs to be able to work better with a variety of browsers whose compatibility with the Web standards they use vary. Have fun!

+ +

{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}

+ +

 

+ +

In this module

+ + + +

 

diff --git a/files/es/learn/html/forms/how_to_structure_an_html_form/index.html b/files/es/learn/html/forms/how_to_structure_an_html_form/index.html new file mode 100644 index 0000000000..45f58520d1 --- /dev/null +++ b/files/es/learn/html/forms/how_to_structure_an_html_form/index.html @@ -0,0 +1,320 @@ +--- +title: Cómo estructurar un formulario HTML +slug: Learn/HTML/Forms/How_to_structure_an_HTML_form +translation_of: Learn/Forms/How_to_structure_a_web_form +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Forms/Your_first_form", "Learn/Forms/Basic_native_form_controls", "Learn/Forms")}}
+ +

Una vez examinados los conceptos básicos, vamos a ver más en detalle los elementos que se utilizan para proporcionar estructura y significado a las diferentes partes de un formulario.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática y de lenguajes HTML.
Objetivo:Entender cómo se estructuran los formularios HTML y se les proporciona semántica para dotarlos de criterios de usabilidad y accesibilidad.
+ +

La flexibilidad que presentan los formularios los convierte en una de las estructuras más complejas en HTML, puesto que puedes crear cualquier tipo de formulario básico a partir de los elementos y atributos destinados a esta función. El uso de una estructura correcta al crear un formulario HTML te ayudará a garantizar que el formulario presente las características de usabilidad y accesibilidad adecuadas.

+ +

El elemento <form>

+ +

El elemento {{HTMLElement ("form")}} define formalmente un formulario y los atributos que determinan el comportamiento del formulario. Cada vez que desees crear un formulario HTML, debes empezar utilizando este elemento y anidando todo el contenido dentro de él. Muchas tecnologías de asistencia y complementos del navegador pueden descubrir elementos {{HTMLElement ("form")}} e implementar códigos de apoyo (hooks) especiales para que sean más fáciles de usar.

+ +

Ya lo vimos en el artículo anterior.

+ +
Advertencia: Está estrictamente prohibido anidar un formulario dentro de otro formulario. Anidar formularios no es una buena idea porque puede ocasionar comportamientos impredecibles.
+ +

Siempre es posible usar controles de formulario fuera de un elemento {{HTMLElement ("form")}}. Si la haces, por defecto ese control no tiene nada que ver con ningún formulario, a menos que lo asocies a algún formulario con el atributo form. Esto se introdujo para permitir vincular explícitamente un control a un formulario, incluso si este no está dentro de él.

+ +

A continuación vamos a exponer los elementos estructurales que encontrarás en un formulario.

+ +

Los elementos <fieldset> y <legend>

+ +

El elemento {{HTMLElement ("fieldset")}} es una forma cómoda de crear grupos de controles de formulario (también denominados widgets) que comparten el mismo propósito, con fines semánticos y de aplicación de estilo. Puedes etiquetar un elemento {{HTMLElement ("fieldset")}} incluyendo un elemento {{HTMLElement ("legend")}} justo debajo de la etiqueta de apertura {{HTMLElement ("fieldset")}}. El contenido textual del elemento {{HTMLElement ("legend")}} describe formalmente el propósito del elemento {{HTMLElement ("fieldset")}} que está incluido dentro.

+ +

Muchas tecnologías de asistencia utilizarán el elemento {{HTMLElement ("legend")}} como si fuera una parte de la etiqueta de cada control dentro del elemento {{HTMLElement ("fieldset")}} correspondiente. Por ejemplo, algunos lectores de pantalla como Jaws y NVDA leerán el contenido de la leyenda antes de decir la etiqueta de cada control.

+ +

Un pequeño ejemplo:

+ +
<form>
+  <fieldset>
+    <legend>Tamaño del zumo de fruta</legend>
+    <p>
+      <input type="radio" name="size" id="size_1" value="small">
+      <label for="size_1">Pequeño</label>
+    </p>
+    <p>
+      <input type="radio" name="size" id="size_2" value="medium">
+      <label for="size_2">Mediano</label>
+    </p>
+    <p>
+      <input type="radio" name="size" id="size_3" value="large">
+      <label for="size_3">Grande</label>
+    </p>
+  </fieldset>
+</form>
+ +
+

Nota: Puedes encontrar este ejemplo en fieldset-legend.html (consúltalo en vivo).

+
+ +

Al leer el formulario anterior, un lector de pantalla dirá «Tamaño del zumo de fruta: pequeño» para el primer control de formulario, «Tamaño del zumo de fruta: mediano» para el segundo y «Tamaño del zumo de fruta: grande» para el tercero.

+ +

El caso de uso que se muestra en este ejemplo es uno de los más importantes. Cada vez que tengas un conjunto de botones de opción, debes anidarlos dentro de un elemento {{HTMLElement ("fieldset")}}. Hay otros casos de uso y el elemento {{HTMLElement ("fieldset")}} también se puede usar en general para seccionar un formulario. Idealmente, los formularios largos deberían tener una extensión de varias páginas, pero si un formulario se alarga y ha de estar contenido en una sola página, colocar las diferentes secciones relacionadas dentro de diferentes conjuntos de campos mejora su usabilidad.

+ +

Debido a la influencia que tiene sobre las tecnologías de asistencia, el elemento {{HTMLElement ("fieldset")}} es uno de los elementos clave para crear formularios accesibles. Sin embargo, no hay que abusar de él. Si es posible, cada vez que crees un formulario, intenta escuchar cómo lo interpreta un lector de pantalla. Si suena raro, intenta mejorar la estructura del formulario.

+ +

El elemento <label>

+ +

Como vimos en el artículo anterior, el elemento {{HTMLElement ("label")}} es la forma formal de definir una etiqueta para un control de un formulario HTML. Este es el elemento más importante si deseas crear formularios accesibles porque cuando se implementan correctamente, los lectores de pantalla leen la etiqueta de un elemento de formulario junto con las instrucciones relacionadas, y esto además resulta muy útil para los usuarios videntes. Tomemos este ejemplo que vimos en el artículo anterior:

+ +
<label for="name">Nombre:</label> <input type="text" id="name" name="user_name">
+ +

Con la etiqueta <label> asociada correctamente con <input> por su atributo for (que contiene el atributo id del elemento <input>), un lector de pantalla leerá algo como «Nombre, editar texto».

+ +

Hay otra forma de asociar un control de formulario con una etiqueta: asociarlo implícitamente anidando el control de formulario dentro de <label>.

+ +
<label for="name">
+  Nombre: <input type="text" id="name" name="user_name">
+</label>
+ +

Incluso en estos casos, se aconseja establecer el atributo for para garantizar que todas las tecnologías de asistencia comprendan la relación entre la etiqueta y el control de formulario.

+ +

Si no hay ninguna etiqueta, o si el control de formulario no está asociado implícita o explícitamente con alguna etiqueta, un lector de pantalla leerá algo así como «Editar texto en blanco», lo cual no es de mucha ayuda.

+ +

¡También se puede hacer clic en las etiquetas!

+ +

Otra ventaja de configurar correctamente las etiquetas es que puedes hacer clic o pulsar en la etiqueta para activar el control de formulario correspondiente. Esto es útil para controles como entradas de texto, donde puedes hacer clic tanto en la etiqueta como en la entrada de texto para proporcionar el foco al control de formulario, pero es útil especialmente para botones de opción y casillas de verificación, porque la zona sensible de este control puede ser muy pequeña, y puede ser útil para facilitar su activación.

+ +

Por ejemplo, al hacer clic en el texto de la etiqueta «Me gustan las cerezas» del ejemplo siguiente, cambiará el estado seleccionado de la casilla de verificación taste_cherry:

+ +
<form>
+  <p>
+    <input type="checkbox" id="taste_1" name="taste_cherry" value="cherry">
+    <label for="taste_1">Me gustan las cerezas</label>
+  </p>
+  <p>
+    <input type="checkbox" id="taste_2" name="taste_banana" value="banana">
+    <label for="taste_2">Me gustan los plátanos</label>
+  </p>
+</form>
+ +
+

Nota: Puedes encontrar este ejemplo en checkbox-label.html (consúltalo en vivo).

+
+ +

Etiquetas múltiples

+ +

Estrictamente hablando, es posible poner varias etiquetas en un solo control de formulario, pero no suele ser una buena idea porque algunas tecnologías de asistencia pueden tener problemas para manejarlas. En caso de tener varias etiquetas, hay que anidar el control de formulario y sus etiquetas dentro de un único elemento {{htmlelement ("label")}}.

+ +

Consideremos este ejemplo:

+ +
<p>Los campos obligatorios se marcan con un <abbr title = "required">*</abbr>.</p>
+
+<!-- Así que esto: -->
+<div>
+  <label for="username">Nombre:</label>
+  <input type="text" name="username">
+  <label for="username"><abbr title="required" aria-label="required">*</abbr></label>
+</div>
+
+<!-- sería mejor hacerlo así: -->
+<div>
+  <label for="username">
+    <span>Nombre:</span>
+    <input id="username" type="text" name="username">
+    <abbr title="required" aria-label="required">*</abbr>
+  </label>
+</div>
+
+<!-- Pero probablemente lo mejor es esto: -->
+<div>
+  <label for="username">Nombre: <abbr title="required" aria-label="required">*</abbr></label>
+  <input id="username" type="text" name="username">
+</div>
+ +

{{EmbedLiveSample("Etiquetas_múltiples", 120, 120)}}

+ +

El párrafo de la parte superior establece una regla para los elementos que son obligatorios. La regla ha de incluirse antes de usarse para que tanto los usuarios videntes como los usuarios que utilizan tecnologías de asistencia y lectores de pantalla, sepan lo que significa antes de encontrar un elemento obligatorio. Pero si bien esto ayuda a informar a los usuarios de lo que significa un asterisco, no es posible confiar plenamente en ello. Cuando un lector de pantalla se encuentre con un asterisco pronunciará «estrella». Cuando un usuario vidente pase el ratón por encima, debería aparecer una etiqueta de «obligatorio», lo cual se logra con el uso del atributo title. Pero los títulos que se leen en voz alta dependen de la configuración del lector de pantalla, por lo que es más fiable incluir también el atributo aria-label, que los lectores de pantalla siempre leen.

+ +

Las variantes anteriores aumentan en efectividad a medida que se avanza por ellas:

+ + + +
+

Nota: Es posible que obtengas resultados ligeramente diferentes dependiendo de tu lector de pantalla. Esta prueba se hizo con VoiceOver (NVDA se comporta de manera similar). Nos encantaría conocer tus experiencias.

+
+ +
+

Nota: Puedes encontrar este ejemplo en GitHub como required-labels.html (o consultarlo en vivo). No pruebes el ejemplo con las dos o tres versiones sin los comentarios porque los lectores de pantalla se confundirán si hay múltiples etiquetas y múltiples entradas con el mismo ID.

+
+ +

Estructuras HTML comunes que se utilizan en los formularios

+ +

Más allá de las estructuras específicas de los formularios web, es bueno recordar que el marcado de los formularios es solo HTML. Esto significa que puedes usar todo el poder del HTML para estructurar un formulario web.

+ +

Como puedes ver en los ejemplos, es una práctica común delimitar una etiqueta y su control de formulario con un elemento {{HTMLElement ("li")}} dentro de una lista {{HTMLElement ("ul")}} o {{HTMLElement ("ol")}}. Los elementos {{HTMLElement ("p")}} y {{HTMLElement ("div")}} también se usan con frecuencia. Se recomiendan las listas para estructurar múltiples casillas de verificación o botones de opción.

+ +

Además del elemento {{HTMLElement ("fieldset")}}, también es una práctica común usar títulos HTML (por ejemplo, {{htmlelement ("h1")}}, {{htmlelement ("h2")}}), y seccionar (por ejemplo, {{htmlelement ("section")}}), para estructurar formas complejas.

+ +

Depende de ti, sobre todo, encontrar un estilo de codificación cómodo que dé como resultado formas con buena accesibilidad y usabilidad. Las secciones independientes con funciones diferentes deben estar contenidas en elementos {{htmlelement ("section")}} separados, con elementos {{htmlelement ("fieldset")}} para contener botones de opción.

+ +

Aprendizaje activo: construir una estructura de formulario

+ +

Pongamos en práctica estas ideas y creemos un formulario un poco más complicado: un formulario de pago. Este formulario contendrá una serie de tipos de control que quizás aún no comprendas. No te preocupes por esto por ahora; en el artículo siguiente descubrirás cómo funcionan (Los controles básicos de formulario originales). Por ahora, lee con detenimiento las descripciones y sigue las instrucciones, y empieza a formarte una idea de qué elementos de delimitación se utilizan para estructurar el formulario y por qué.

+ +
    +
  1. Para comenzar, haz una copia local de nuestro archivo de plantilla en blanco y el CSS de nuestro formulario de pago en un nuevo directorio de tu ordenador.
  2. +
  3. Añade dentro del elemento HTML {{htmlelement ("head")}} la línea siguiente para aplicar el CSS al HTML: +
    <link href="payment-form.css" rel="stylesheet">
    +
  4. +
  5. A continuación, añade el elemento externo {{htmlelement ("form")}} para crear tu formulario: +
    <form>
    +
    +</form>
    +
  6. +
  7. Añade un encabezado y un párrafo dentro de las etiquetas <form>> para informar a los usuarios cómo se marcan los campos obligatorios: +
    <h1>Forma de pago</h1>
    +<p>Los campos obligatorios van seguidos de <strong> <abbr title = "required"> * </abbr> </strong>.</p>
    +
  8. +
  9. A continuación añadimos al formulario una sección de código más grande, justo debajo de nuestra entrada anterior. Aquí verás que delimitamos con un elemento {{htmlelement ("section")}} independiente los campos con la información de contacto. Además, hay un conjunto de dos botones de opción, cada uno de los cuales colocamos dentro de su elemento de lista ({{htmlelement ("li")}}) propio. También hay dos entradas de texto estándar {{htmlelement ("input")}} y sus elementos {{htmlelement ("label")}} asociados, cada uno anidado dentro de un elemento {{htmlelement ("p")}} y una entrada de texto para introducir una contraseña. Añade este código a tu formulario: +
    <section>
    +    <h2>Información de contacto</h2>
    +    <fieldset>
    +      <legend>Título</legend>
    +      <ul>
    +          <li>
    +            <label for="title_1">
    +              <input type="radio" id="title_1" name="title" value="K" >
    +              Rey
    +            </label>
    +          </li>
    +          <li>
    +            <label for="title_2">
    +              <input type="radio" id="title_2" name="title" value="Q">
    +              Reina
    +            </label>
    +          </li>
    +          <li>
    +            <label for="title_3">
    +              <input type="radio" id="title_3" name="title" value="J">
    +              Bufón
    +            </label>
    +          </li>
    +      </ul>
    +    </fieldset>
    +    <p>
    +      <label for="name">
    +        <span>Nombre:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="text" id="name" name="username">
    +    </p>
    +    <p>
    +      <label for="mail">
    +        <Span>Correo electrónico:</ span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="email" id="mail" name="usermail">
    +    </p>
    +    <p>
    +      <label for="pwd">
    +        <span>Contraseña:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="password" id="pwd" name="password">
    +    </p>
    +</section>
    +
  10. +
  11. La segunda <section> de nuestro formulario es la información de pago. Hay tres controles diferentes, junto con sus etiquetas, cada uno contenido dentro de un elemento <p>. El primero es un menú desplegable ({{htmlelement ("select")}}) para seleccionar el tipo de tarjeta de crédito. El segundo es un elemento <input> de tipo tel, para introducir un número de tarjeta de crédito. Si bien podríamos haber usado el tipo number, no queremos una interfaz de usuario con control de número. El último es un elemento <input> de tipo date, para introducir la fecha de caducidad de la tarjeta; aparecerá como un control de selección de fecha en navegadores compatibles, y como una entrada de texto normal en navegadores no compatibles. Estos tipos de entrada más nuevos volverán a aparecer en el artículo Tipos de entrada HTML5.
    +
    + Introduce los datos siguientes a continuación de la sección anterior: +
    <section>
    +    <h2>Información de pago</h2>
    +    <p>
    +      <label for="card">
    +        <span>Tipo de tarjeta:</span>
    +      </label>
    +      <select id="card" name="usercard">
    +        <option value="visa">Visa</option>
    +        <option value="mc">Mastercard</option>
    +        <option value="amex">American Express</option>
    +      </select>
    +    </p>
    +    <p>
    +      <label for="number">
    +        <span>Número de tarjeta:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +      </label>
    +      <input type="tel" id="number" name="cardnumber">
    +    </p>
    +    <p>
    +      <label for="date">
    +        <span>Fecha de caducidad:</span>
    +        <strong><abbr title="required">*</abbr></strong>
    +        <em>el formato mm/aa</em>
    +      </label>
    +      <input type="date" id="date" name="expiration">
    +    </p>
    +</section>
    +
  12. +
  13. La última sección que añadimos es mucho más simple y contiene solo un {{htmlelement ("button")}} de tipo submit, para enviar los datos del formulario. Añádelo al final de tu formulario: +
    <p> <button type="submit">Validar el pago</button> </p>
    +
  14. +
+ +

Debajo puedes ver en acción el formulario terminado (también lo encontrarás en GitHub; consulta el código fuente de nuestro payment-form.html y ejecútalo en vivo):

+ +

{{EmbedLiveSample("A_payment_form","100%",620, "", "/en-US/Learn/Forms/How_to_structure_a_web_form/Example")}}

+ +

¡Prueba tus habilidades!

+ +

Has llegado al final de este artículo pero ¿puedes recordar la información más importante? Puedes encontrar pruebas adicionales para comprobar que has comprendido la información antes de continuar — visita Prueba tus habilidades: Estructura de formularios.

+ +

Resumen

+ +

Ahora tienes todos los conocimientos necesarios para estructurar adecuadamente tus formularios web. Expondremos muchas de las características que se presentan aquí en los artículos siguientes, y el próximo artículo analizará con más detalle el uso de todos los diferentes tipos de controles de formulario que vas a querer usar para recopilar la información de tus usuarios.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Forms/Your_first_form", "Learn/Forms/Basic_native_form_controls", "Learn/Forms")}}

+ +

En este módulo

+ + + +

Temas avanzados

+ + diff --git a/files/es/learn/html/forms/index.html b/files/es/learn/html/forms/index.html new file mode 100644 index 0000000000..c607c7993a --- /dev/null +++ b/files/es/learn/html/forms/index.html @@ -0,0 +1,366 @@ +--- +title: Formularios HTML +slug: Learn/HTML/Forms +tags: + - Featured + - Forms + - Formulario(2) + - Guide + - Guía + - HTML + - NeedsTranslation + - TopicStub + - Web +translation_of: Learn/Forms +--- +

Esta guía está constituida por una serie de artículos que te ayudarán a dominar los formularios en HTML.   El formulario HTML  es una herramienta  cuya finalidad es interactuar con el usuario; sin embargo, debido a razones históricas y técnicas, no siempre resulta obvio como explotar su enorme potencial. En esta guía, cubriremos todos los aspectos de los formularios HTML, desde su estructura hasta su estilo, desde la manipulación de sus datos hasta los widgets personalizados. ¡Aprenderás a disfrutar de las grandes prestaciones que nos brindan!

+ +

Artículos

+ +
    +
  1. Mi primer formulario HTML
  2. +
  3. Cómo estructurar un formulario HTML
  4. +
  5. Los widgets nativos de formulario
  6. +
  7. CSS para formularios HTML +
      +
    1. Aplicando estilos a formularios HTML
    2. +
    3. Estilos avanzados para formularios HTML
    4. +
    5. Tabla de compatibilidad de propiedades para widgets de formulario
    6. +
    +
  8. +
  9. Enviando y recibiendo datos
  10. +
  11. Validación de los datos del formulario
  12. +
  13. Cómo crear un widget de formulario personalizado
  14. +
  15. Enviando formularios mediante JavaScript +
      +
    1. Usando el objeto FormData
    2. +
    +
  16. +
  17. Formularios HTML en navegadores antiguos
  18. +
+ +

Documentación HTML

+ +

HTML Elements

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementoInterfaz DOM relacionadaDescripción
{{HTMLElement("button")}}{{domxref("HTMLButtonElement")}}El elemento  button representa un boton clickeable.
{{HTMLElement("datalist")}}{{domxref("HTMLDataListElement")}}El elemento datalist element contiene un conjunto de elementos{{ HTMLElement("option") }} que representan posibles opciones para el valor de otros elementos del formulario.
{{HTMLElement("fieldset")}}{{domxref("HTMLFieldSetElement")}}El  fieldset se usa para agrupar distintos elementos dentro de un formulario.
{{HTMLElement("form")}}{{domxref("HTMLFormElement")}}El elemento  form representa una seccion del documento html que contiene elementos interactivos a traves de los cuales se le permite al usuario enviar informacion hacia un servidor web.
{{HTMLElement("input")}}{{domxref("HTMLInputElement")}}El elemento   input es usado para crear controles interactivos para los formularios.
{{HTMLElement("keygen")}}{{domxref("HTMLKeygenElement")}}El elemento keygen existe para facilitar la generación de llaves u el envío de las llaves publicas como parte de un formulario HTML.
{{HTMLElement("label")}}{{domxref("HTMLLabelElement")}}El  label determina un título para un item de la interfaz del usuario.
{{HTMLElement("legend")}}{{domxref("HTMLLegendElement")}}El elemento legend  representa una etiqueta para el contenido del elemento {{ HTMLElement("fieldset") }} que lo contiene.
{{HTMLElement("meter")}}{{domxref("HTMLMeterElement")}}EL elemento meter  representa un valor escalar dentro de un rango conocido, o un valor fraccional.
{{HTMLElement("optgroup")}}{{domxref("HTMLOptGroupElement")}} +

El elemento optgroup crea un grupo de opciones dentro de un elemento {{ HTMLElement("select") }} .

+
{{HTMLElement("option")}}{{domxref("HTMLOptionElement")}}El elemento option es usado para crear un control de opcion que representa un item dentro de alguno de los elementos {{ HTMLElement("select") }}, {{ HTMLElement("optgroup") }} o {{ HTMLElement("datalist") }} .
{{HTMLElement("output")}}{{domxref("HTMLOutputElement")}}El elemento output representa un resultado de un calculo.
{{HTMLElement("progress")}}{{domxref("HTMLProgressElement")}}El elemento progress es usado para mostrar el progreso de la realización de una tarea.
{{HTMLElement("select")}}{{domxref("HTMLSelectElement")}}El elemento select representa el control que presenta un menu de opciones.
{{HTMLElement("textarea")}}{{domxref("HTMLTextAreaElement")}}EL elemento textarea representa un campo multi-linea de edicion de text plano.
+ +
+

Nota: Todos los elementos de formulario, al igual que el resto de elementos HTML, soportan la interfaz DOM {{domxref("HTMLElement")}}.

+
+ +

HTML Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre del atributoElementosDescripción
accept{{ HTMLElement("form") }}, {{ HTMLElement("input") }}Lista de tipos que acepta el servidor, típicamente un tipo de fichero.
accept-charset{{ HTMLElement("form") }}Lista de charsets (conjuntos de caracteres) aceptados.
action{{ HTMLElement("form") }}La URI del programa con el que procesar la información enviada a mediante el formulario.
autocomplete{{ HTMLElement("form") }}, {{ HTMLElement("input") }}Indica si los controles en este formulario serán o no autocompletados por el navegador
autofocus{{ HTMLElement("button") }}, {{ HTMLElement("input") }}, {{ HTMLElement("keygen") }}, {{ HTMLElement("select") }}, {{ HTMLElement("textarea") }}El elemento debería poseer el foco automáticamente tras cargar  la página.
challenge{{ HTMLElement("keygen") }}Una cadena de comprobación que es enviada junto con la clave pública.
checked{{ HTMLElement("input") }}Indica si el elemento debe estar seleccionado (checked) tras cargar la página.
cols{{ HTMLElement("textarea") }}Define el número de columnas en un elemento de tipo textarea.
data{{ HTMLElement("object") }}Especifica la URL del recurso.
dirname{{ HTMLElement("input") }}, {{ HTMLElement("textarea") }} 
disabled{{ HTMLElement("button") }}, {{ HTMLElement("fieldset") }}, {{ HTMLElement("input") }}, {{ HTMLElement("keygen") }}, {{ HTMLElement("optgroup") }}, {{ HTMLElement("option") }}, {{ HTMLElement("select") }}, {{ HTMLElement("textarea") }}Indica si el usuario puede o no interactuar con el elemento.
enctype{{ HTMLElement("form") }}Define el tipo de contenido del formulario cuando el método de envío es POST.
for{{ HTMLElement("label") }}, {{ HTMLElement("output") }} +

Establece una asociación con otros elementos

+
form{{ HTMLElement("button") }}, {{ HTMLElement("fieldset") }}, {{ HTMLElement("input") }}, {{ HTMLElement("keygen") }}, {{ HTMLElement("label") }}, {{ HTMLElement("meter") }}, {{ HTMLElement("object") }}, {{ HTMLElement("output") }}, {{ HTMLElement("progress") }}, {{ HTMLElement("select") }}, {{ HTMLElement("textarea") }}Indica el elemento form que contiene este elemento.
high{{ HTMLElement("meter") }}Indicates the lower bound of the upper range.
keytype{{ HTMLElement("keygen") }}Especifica el tipo de clave generada.
list{{ HTMLElement("input") }}Determina una lista de opciones predefinidas para sugerir al usuario.
low{{ HTMLElement("meter") }}Indicates the upper bound of the lower range.
max{{ HTMLElement("input") }}, {{ HTMLElement("meter") }}, {{ HTMLElement("progress") }}Indica el máximo valor permitido.
maxlength{{ HTMLElement("input") }}, {{ HTMLElement("textarea") }}Define el máximo número de caracteres permitidos en el elemento.
method{{ HTMLElement("form") }} +

Define qué método HTTP se usará al enviar el formulario. puede ser GET (por defecto) o POST

+
min{{ HTMLElement("input") }}, {{ HTMLElement("meter") }}Indica el mínimo valor permitido.
multiple{{ HTMLElement("input") }}, {{ HTMLElement("select") }}Indica si mútiples valores pueden ser introducidos en un input de tipo email o file.
name{{ HTMLElement("button") }}, {{ HTMLElement("form") }}, {{ HTMLElement("fieldset") }}, {{ HTMLElement("input") }}, {{ HTMLElement("keygen") }}, {{ HTMLElement("output") }}, {{ HTMLElement("select") }}, {{ HTMLElement("textarea") }}Especifica el nombre del elemento. Este nombre se usará asociado al dato que contiene al enviar al servidor el formulario.
novalidate{{ HTMLElement("form") }}Indica que el formulario no debería validarse al momento de ser enviado.
optimum{{ HTMLElement("meter") }}Indica el valor numérico óptimo.
pattern{{ HTMLElement("input") }}Establece la expresión regular con la que validar el valor del elemento.
placeholder{{ HTMLElement("input") }}, {{ HTMLElement("textarea") }}Proporciona una pista al usuario de lo que el campo debe contener. Se muestra cuando el campo está vacío.
readonly{{ HTMLElement("input") }}, {{ HTMLElement("textarea") }}Indica si el elemento se puede o no editar.
required{{ HTMLElement("input") }}, {{ HTMLElement("select") }}, {{ HTMLElement("textarea") }}Cuando un campo del formulario es requerido, el usuario no puede dejarlo vacío.
rows{{ HTMLElement("textarea") }}Defines the number of rows in a textarea.
selected{{ HTMLElement("option") }}En una lista de selección, la opción con el atributo selected será la que está seleccionada por defecto
size{{ HTMLElement("input") }}, {{ HTMLElement("select") }}Defina la anchura del elemento (en píxeles). Si el elemento es de tipo text o password el ancho se referirá al número de caracteres.
src{{ HTMLElement("img") }}El URL del recurso
step{{ HTMLElement("input") }}Determina el incremento de cada paso con el que se cubre un rango desde un valor mínimo hasta un valor máximo.
target{{ HTMLElement("form") }} 
type{{ HTMLElement("button") }}, {{ HTMLElement("input") }}Determina el tipo del elemento.
usemap{{ HTMLElement("input") }} 
value{{ HTMLElement("button") }}, {{ HTMLElement("option") }}, {{ HTMLElement("input") }}, {{ HTMLElement("meter") }}, {{ HTMLElement("progress") }}Establece el valor actual del elemento.
wrap{{ HTMLElement("textarea") }}Cuando un texto tiene una longitud mayor que el ancho del elemento sobre el que se muestra, determina si el elemento debe simular saltos de línea para que todo el texto quede visible en el elemento.
+ +

Referencia a la normativa

+ + diff --git a/files/es/learn/html/forms/property_compatibility_table_for_form_controls/index.html b/files/es/learn/html/forms/property_compatibility_table_for_form_controls/index.html new file mode 100644 index 0000000000..115b5580fe --- /dev/null +++ b/files/es/learn/html/forms/property_compatibility_table_for_form_controls/index.html @@ -0,0 +1,2003 @@ +--- +title: Tabla de compatibilidad de propiedades CSS para controles de formulario +slug: Learn/HTML/Forms/Property_compatibility_table_for_form_controls +translation_of: Learn/Forms/Property_compatibility_table_for_form_controls +--- +
{{learnsidebar}}
+ +

Las siguientes tablas de compatibilidad intentan resumir el estado del soporte de CSS para formularios HTML. Debido a la complejidad de los formularios CSS y HTML, estas tablas no se pueden considerar una referencia perfecta. Sin embargo, le darán una buena idea de lo que se puede y no se puede hacer, lo que le ayudará al aprender a hacer las cosas.

+ +

Cómo leer las tablas

+ +

Valores

+ +

Para cada propiedad, hay cuatro valores posibles:

+ +
+
Si
+
Existe un soporte razonablemente consistente para la propiedad en todos los navegadores. Es posible que aún enfrente efectos secundarios extraños en ciertos casos extremos.
+
Parcial
+
Si bien la propiedad funciona, con frecuencia puede enfrentar efectos secundarios extraños o inconsistencias. Probablemente debería evitar estas propiedades a menos que primero domine esos efectos secundarios.
+
No
+
La propiedad simplemente no funciona o es tan inconsistente que no es confiable.
+
n.a.
+
La propiedad no tiene ningún significado para este tipo de widget.
+
+ +

Representación

+ +

Para cada propiedad hay dos representaciones posibles:

+ +
+
N (Normal)
+
Indica que la propiedad se aplica tal cual
+
T (Retocada)
+
Indica que la propiedad se aplica con la regla adicional como se muestra a continuación:
+
+ +
* {
+  /* Turn off the native look and feel */
+  -webkit-appearance: none;
+  appearance: none;
+
+/* for Internet Explorer */
+  background: none;
+}
+ +

Tablas de compatibilidad

+ +

Comportamientos globales

+ +

Algunos comportamientos son comunes a muchos navegadores a nivel global::

+ +
+
{{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("border-radius")}}, {{cssxref("height")}}
+
El uso de una de estas propiedades puede desactivar parcial o totalmente la apariencia nativa de los widgets en algunos navegadores. Tenga cuidado cuando los use.
+
{{cssxref("line-height")}}
+
Esta propiedad se admite de forma inconsistente en todos los navegadores y debe evitarla.
+
{{cssxref("text-decoration")}}
+
Esta propiedad no es compatible con el navegador Opera en widgets de formulario.
+
{{cssxref("text-overflow")}}
+
Opera, Safari, y IE9 no admiten esta propiedad en widgets de formulario.
+
{{cssxref("text-shadow")}}
+
Opera no admite {{cssxref("text-shadow")}} en widgets de formularios e IE9 no lo admite en absoluto.
+
+ +

Text fields

+ +

See the {{htmlelement("input/text", "text")}}, {{htmlelement("input/search", "search")}}, and {{htmlelement("input/password", "password")}} input types.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}Partial[1][2]Yes +
    +
  1. WebKit browsers (mostly on Mac OSX and iOS) use the native look & feel for the search fields. Therefore, it's required to use -webkit-appearance:none to be able to apply this property to search fields.
  2. +
  3. On Windows 7, Internet Explorer 9 does not apply the border unless background:none is applied.
  4. +
+
{{cssxref("border")}}Partial[1][2]Yes +
    +
  1. WebKit browsers (mostly on Mac OSX and iOS) use the native look & feel for the search fields. Therefore, it's required to use -webkit-appearance:none to be able to apply this property to search fields.
  2. +
  3. On Windows 7, Internet Explorer 9 does not apply the border unless background:none is applied.
  4. +
+
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}Partial[1][2]Yes +
    +
  1. WebKit browsers (mostly on Mac OSX and iOS) use the native look & feel for the search fields. Therefore, it's required to use -webkit-appearance:none to be able to apply this property to search fields.
  2. +
  3. On Windows 7, Internet Explorer 9 does not apply the border unless background:none is applied.
  4. +
+
Text and font
{{cssxref("color")}}[1]YesYes +
    +
  1. If the {{cssxref("border-color")}} property is not set, some WebKit based browsers will apply the {{cssxref("color")}} property to the border as well as the font on {{htmlelement("textarea")}}s.
  2. +
+
{{cssxref("font")}}YesYesSee the note about {{cssxref("line-height")}}
{{cssxref("letter-spacing")}}YesYes
{{cssxref("text-align")}}YesYes
{{cssxref("text-decoration")}}PartialPartialSee the note about Opera
{{cssxref("text-indent")}}Partial[1]Partial[1] +
    +
  1. IE9 supports this property only on {{htmlelement("textarea")}}s, whereas Opera only supports it on single line text fields.
  2. +
+
{{cssxref("text-overflow")}}PartialPartial
{{cssxref("text-shadow")}}PartialPartial
{{cssxref("text-transform")}}YesYes
Border and background
{{cssxref("background")}}Partial[1]Yes +
    +
  1. WebKit browsers (mostly on Mac OSX and iOS) use the native look & feel for the search fields. Therefore, it's required to use -webkit-appearance:none to be able to apply this property to search fields. On Windows 7, Internet Explorer 9 does not apply the border unless background:none is applied.
  2. +
+
{{cssxref("border-radius")}}Partial[1][2]Yes +
    +
  1. WebKit browsers (mostly on Mac OSX and iOS) use the native look & feel for the search fields. Therefore, it's required to use -webkit-appearance:none to be able to apply this property to search fields. On Windows 7, Internet Explorer 9 does not apply the border unless background:none is applied.
  2. +
  3. On Opera the {{cssxref("border-radius")}} property is applied only if an explicit border is set.
  4. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
+ +

Buttons

+ +

See the {{htmlelement("input/button", "button")}}{{htmlelement("input/submit", "submit")}}, and {{htmlelement("input/reset", "reset")}} input types and the {{htmlelement("button")}} element.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}Partial[1]Yes +
    +
  1. This property is not applied on WebKit based browsers on Mac OSX or iOS.
  2. +
+
{{cssxref("border")}}PartialYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}Partial[1]Yes +
    +
  1. This property is not applied on WebKit based browsers on Mac OSX or iOS.
  2. +
+
Text and font
{{cssxref("color")}}YesYes
{{cssxref("font")}}YesYesSee the note about {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}YesYes
{{cssxref("text-align")}}NoNo
{{cssxref("text-decoration")}}PartialYes
{{cssxref("text-indent")}}YesYes
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}PartialPartial
{{cssxref("text-transform")}}YesYes
Border and background
{{cssxref("background")}}YesYes
{{cssxref("border-radius")}}Yes[1]Yes[1] +
    +
  1. On Opera the {{cssxref("border-radius")}} property is applied only if an explicit border is set.
  2. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
+ +

Number

+ +

See the  {{htmlelement("input/number", "number")}} input type. There is no standard way to change the style of spinners used to change the value of the field, with the spinners on Safari being outside the field.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}Partial[1]Partial[1] +
    +
  1. On Opera, the spinners are zoomed in, which can hide the content of the field.
  2. +
+
{{cssxref("border")}}YesYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}Partial[1]Partial[1] +
    +
  1. On Opera, the spinners are zoomed in, which can hide the content of the field.
  2. +
+
Text and font
{{cssxref("color")}}YesYes
{{cssxref("font")}}YesYesSee the note about {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}YesYes
{{cssxref("text-align")}}YesYes
{{cssxref("text-decoration")}}PartialPartial
{{cssxref("text-indent")}}YesYes
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}PartialPartial
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}NoNo +

Supported but there is too much inconsistency between browsers to be reliable.

+
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
+ +

Check boxes and radio buttons

+ +

See the {{htmlelement("input/checkbox", "checkbox")}} and {{htmlelement("input/radio", "radio")}} input types.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}No[1]No[1] +
    +
  1. Some browsers add extra margins and others stretch the widget.
  2. +
+
{{cssxref("height")}}No[1]No[1] +
    +
  1. Some browsers add extra margins and others stretch the widget.
  2. +
+
{{cssxref("border")}}NoNo
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}NoNo
Text and font
{{cssxref("color")}}N.A.N.A.
{{cssxref("font")}}N.A.N.A.
{{cssxref("letter-spacing")}}N.A.N.A.
{{cssxref("text-align")}}N.A.N.A.
{{cssxref("text-decoration")}}N.A.N.A.
{{cssxref("text-indent")}}N.A.N.A.
{{cssxref("text-overflow")}}N.A.N.A.
{{cssxref("text-shadow")}}N.A.N.A.
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}NoNo
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
+ +

Select boxes (single line)

+ +

See the {{htmlelement("select")}}{{htmlelement("optgroup")}} and  {{htmlelement("option")}} elements.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}Partial[1]Partial[1] +
    +
  1. This property is okay on the {{htmlelement("select")}} element, but it cannot be the case on the {{htmlelement("option")}} or {{htmlelement("optgroup")}} elements.
  2. +
+
{{cssxref("height")}}NoYes
{{cssxref("border")}}PartialYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}No[1]Partial[2] +
    +
  1. The property is applied, but in an inconsistent way between browsers on Mac OSX.
  2. +
  3. The property is well applied on the {{htmlelement("select")}} element, but is inconsistently handled on {{htmlelement("option")}} and {{htmlelement("optgroup")}} elements.
  4. +
+
Text and font
{{cssxref("color")}}Partial[1]Partial[1] +
    +
  1. On Mac OSX, WebKit based browsers do not support this property on native widgets and they, along with Opera, do not support it at all on {{htmlelement("option")}} and {{htmlelement("optgroup")}} elements.
  2. +
+
{{cssxref("font")}}Partial[1]Partial[1] +
    +
  1. On Mac OSX, WebKit based browsers do not support this property on native widgets and they, along with Opera, do not support it at all on {{htmlelement("option")}} and {{htmlelement("optgroup")}} elements.
  2. +
+
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. IE9 does not support this property on {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements; WebKit based browsers on Mac OSX do not support this property on {{htmlelement("option")}} and {{htmlelement("optgroup")}} elements.
  2. +
+
{{cssxref("text-align")}}No[1]No[1] +
    +
  1. IE9 on Windows 7 and WebKit based browsers on Mac OSX do not support this property on this widget.
  2. +
+
{{cssxref("text-decoration")}}Partial[1]Partial[1] +
    +
  1. Only Firefox provides full support for this property. Opera does not support this property at all and other browsers only support it on the {{htmlelement("select")}} element.
  2. +
+
{{cssxref("text-indent")}}Partial[1][2]Partial[1][2] +
    +
  1. Most of the browsers only support this property on the {{htmlelement("select")}} element.
  2. +
  3. IE9 does not support this property.
  4. +
+
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}Partial[1][2]Partial[1][2] +
    +
  1. Most of the browsers only support this property on the {{htmlelement("select")}} element.
  2. +
  3. IE9 does not support this property.
  4. +
+
{{cssxref("text-transform")}}Partial[1]Partial[1] +
    +
  1. Most of the browsers only support this property on the {{htmlelement("select")}} element.
  2. +
+
Border and background
{{cssxref("background")}}Partial[1]Partial[1] +
    +
  1. Most of the browsers only support this property on the {{htmlelement("select")}} element.
  2. +
+
{{cssxref("border-radius")}}Partial[1]Partial[1]
{{cssxref("box-shadow")}}NoPartial[1]
+ +

Note Firefox does not provide any way to change the down arrow on the {{htmlelement("select")}} element.

+ +

Select boxes (multiline)

+ +

See the {{htmlelement("select")}}, {{htmlelement("optgroup")}} and  {{htmlelement("option")}} elements and the size attribute.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}YesYes
{{cssxref("border")}}YesYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}Partial[1]Partial[1] +
    +
  1. Opera does not support {{cssxref("padding-top")}} and {{cssxref("padding-bottom")}} on the {{htmlelement("select")}} element.
  2. +
+
Text and font
{{cssxref("color")}}YesYes
{{cssxref("font")}}YesYesSee the note about {{cssxref("line-height")}}.
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. IE9 does not support this property on {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements; WebKit based browsers on Mac OSX do not support this property on {{htmlelement("option")}} and {{htmlelement("optgroup")}} elements.
  2. +
+
{{cssxref("text-align")}}No[1]No[1] +
    +
  1. IE9 on Windows 7 and WebKit based browser on Mac OSX do not support this property on this widget.
  2. +
+
{{cssxref("text-decoration")}}No[1]No[1] +
    +
  1. Only supported by Firefox and IE9+.
  2. +
+
{{cssxref("text-indent")}}NoNo
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}NoNo
{{cssxref("text-transform")}}Partial[1]Partial[1] +
    +
  1. Most of the browsers only support this property on the {{htmlelement("select")}} element.
  2. +
+
Border and background
{{cssxref("background")}}YesYes
{{cssxref("border-radius")}}Yes[1]Yes[1] +
    +
  1. On Opera the {{cssxref("border-radius")}} property is applied only if an explicit border is set.
  2. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
+ +

Datalist

+ +

See the {{htmlelement("datalist")}} and {{htmlelement("input")}} elements and the list attribute.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo
{{cssxref("height")}}NoNo
{{cssxref("border")}}NoNo
{{cssxref("margin")}}NoNo
{{cssxref("padding")}}NoNo
Text and font
{{cssxref("color")}}NoNo
{{cssxref("font")}}NoNo
{{cssxref("letter-spacing")}}NoNo
{{cssxref("text-align")}}NoNo
{{cssxref("text-decoration")}}NoNo
{{cssxref("text-indent")}}NoNo
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}NoNo
{{cssxref("text-transform")}}NoNo
Border and background
{{cssxref("background")}}NoNo
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
+ +

File picker

+ +

See the {{htmlelement("input/file", "file")}} input type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo
{{cssxref("height")}}NoNo
{{cssxref("border")}}NoNo
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}NoNo
Text and font
{{cssxref("color")}}YesYes
{{cssxref("font")}}No[1]No[1] +
    +
  1. Supported, but there is too much inconsistency between browsers to be reliable.
  2. +
+
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. Many browsers apply this property to the select button.
  2. +
+
{{cssxref("text-align")}}NoNo
{{cssxref("text-decoration")}}NoNo
{{cssxref("text-indent")}}Partial[1]Partial[1] +
    +
  1. It acts more or less like an extra left margin outside the widget.
  2. +
+
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}NoNo
{{cssxref("text-transform")}}NoNo
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. Supported, but there is too much inconsistency between browsers to be reliable.
  2. +
+
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
+ +

Date pickers

+ +

See the {{htmlelement("input/date", "date")}} and {{htmlelement("input/time", "time")}} input types. Many properties are supported, but there is too much inconstency between browsers to be reliable.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo
{{cssxref("height")}}NoNo
{{cssxref("border")}}NoNo
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}NoNo
Text and font
{{cssxref("color")}}NoNo
{{cssxref("font")}}NoNo
{{cssxref("letter-spacing")}}NoNo
{{cssxref("text-align")}}NoNo
{{cssxref("text-decoration")}}NoNo
{{cssxref("text-indent")}}NoNo
{{cssxref("text-overflow")}}NoNo
{{cssxref("text-shadow")}}NoNo
{{cssxref("text-transform")}}NoNo
Border and background
{{cssxref("background")}}NoNo
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
+ +

Color pickers

+ +

See the {{htmlelement("input/color", "color")}} input type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}No[1]Yes +
    +
  1. Opera handles this like a select widget with the same restriction.
  2. +
+
{{cssxref("border")}}YesYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}No[1]Yes +
    +
  1. Opera handles this like a select widget with the same restriction.
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A.
{{cssxref("font")}}N.A.N.A.
{{cssxref("letter-spacing")}}N.A.N.A.
{{cssxref("text-align")}}N.A.N.A.
{{cssxref("text-decoration")}}N.A.N.A.
{{cssxref("text-indent")}}N.A.N.A.
{{cssxref("text-overflow")}}N.A.N.A.
{{cssxref("text-shadow")}}N.A.N.A.
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. Supported, but there is too much inconsistency between browsers to be reliable.
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Meters and progress

+ +

See the {{htmlelement("meter")}} and {{htmlelement("progress")}} elements:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}YesYes
{{cssxref("border")}}PartialYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}YesPartial[1] +
    +
  1. Chrome hides the {{htmlelement("progress")}} and {{htmlelement("meter")}} element when the {{cssxref("padding")}} property is applied on a tweaked element.
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A.
{{cssxref("font")}}N.A.N.A.
{{cssxref("letter-spacing")}}N.A.N.A.
{{cssxref("text-align")}}N.A.N.A.
{{cssxref("text-decoration")}}N.A.N.A.
{{cssxref("text-indent")}}N.A.N.A.
{{cssxref("text-overflow")}}N.A.N.A.
{{cssxref("text-shadow")}}N.A.N.A.
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. Supported, but there is too much inconsistency between browsers to be reliable.
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Range

+ +

See the {{htmlelement("input/range", "range")}} input type. There is no standard way to change the style of the range grip and Opera has no way to tweak the default rendering of the range widget.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}Partial[1]Partial[1] +
    +
  1. Chrome and Opera add some extra space around the widget, whereas Opera on Windows 7 stretches the range grip.
  2. +
+
{{cssxref("border")}}NoYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}Partial[1]Yes +
    +
  1. The {{cssxref("padding")}} is applied, but has no visual effect.
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A.
{{cssxref("font")}}N.A.N.A.
{{cssxref("letter-spacing")}}N.A.N.A.
{{cssxref("text-align")}}N.A.N.A.
{{cssxref("text-decoration")}}N.A.N.A.
{{cssxref("text-indent")}}N.A.N.A.
{{cssxref("text-overflow")}}N.A.N.A.
{{cssxref("text-shadow")}}N.A.N.A.
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. Supported, but there is too much inconsistency between browsers to be reliable.
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Image buttons

+ +

See the {{htmlelement("input/image", "image")}} input type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes
{{cssxref("height")}}YesYes
{{cssxref("border")}}YesYes
{{cssxref("margin")}}YesYes
{{cssxref("padding")}}YesYes
Text and font
{{cssxref("color")}}N.A.N.A.
{{cssxref("font")}}N.A.N.A.
{{cssxref("letter-spacing")}}N.A.N.A.
{{cssxref("text-align")}}N.A.N.A.
{{cssxref("text-decoration")}}N.A.N.A.
{{cssxref("text-indent")}}N.A.N.A.
{{cssxref("text-overflow")}}N.A.N.A.
{{cssxref("text-shadow")}}N.A.N.A.
{{cssxref("text-transform")}}N.A.N.A.
Border and background
{{cssxref("background")}}YesYes
{{cssxref("border-radius")}}Partial[1]Partial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
{{cssxref("box-shadow")}}Partial[1]Partial[1] +
    +
  1. IE9 does not support this property.
  2. +
+
+ +

See also

+ +

Learning path

+ + + +

Advanced Topics

+ + diff --git a/files/es/learn/html/forms/prueba_tus_habilidades_colon__controles_html5/index.html b/files/es/learn/html/forms/prueba_tus_habilidades_colon__controles_html5/index.html new file mode 100644 index 0000000000..b73c8d4442 --- /dev/null +++ b/files/es/learn/html/forms/prueba_tus_habilidades_colon__controles_html5/index.html @@ -0,0 +1,75 @@ +--- +title: 'Prueba tus habilidades: controles HTML5' +slug: 'Learn/HTML/Forms/Prueba_tus_habilidades:_controles_HTML5' +tags: + - Aprendizaje + - Evaluación + - Formulário + - HTML5 + - Principiante +translation_of: 'Learn/Forms/Test_your_skills:_HTML5_controls' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba es evaluar si has comprendido nuestro artículo The HTML5 input types.

+ +
+

Nota: Puedes intentar resolver esta prueba en los editores interactivos más abajo, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePenjsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te atascas, pide ayuda — mira la sección Evaluación o ayuda adicional al final de esta página.

+
+ +

Controles HTML5 1

+ +

Primero exploraremos algunos de los tipos nuevos de input en HTML5. Crea las etiquetas input apropiadas para que un usuario actualice sus detalles para:

+ +
    +
  1. Email
  2. +
  3. Website
  4. +
  5. Número de teléfono
  6. +
  7. Color favorito
  8. +
+ +

Intenta actualizar el código en vivo más abajo para retrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/tasks/html5-controls/html5-controls1.html", '100%', 700)}}

+ +
+

Descarga el código inicial de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Controles HTML5 2

+ +

A continuación, queremos que implementes un control deslizante para permitir al usuario escoger el número máximo de personas para invitar a su fiesta.

+ +
    +
  1. Implemente un control deslizante básico que acompañe a la etiqueta provista.
  2. +
  3. Establezca un valor minimo de 1, uno máximo de 30 y un valor inicial de 10.
  4. +
  5. Crea un elemento de salida correspondiente para poner el valor actual del deslizador. Asígnale la clase invite-output, y asocialo semanticamente con le entrada. Si haces esto correctamente, el JavaScript incluido en la página automáticamente actualizará el valor cuando se deslice el control.
  6. +
+ +

Intenta actualizar el código en vivo más abajo para retrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/tasks/html5-controls/html5-controls2.html", '100%', 700)}}

+ +
+

Descarga el código inicial de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos que se encuentran más arriba.

+ +

Si deseas que tu trabajo sea evaluado, o estás atorado y quieres solicitar ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea con capacidad de compartir como CodePenjsFiddle, o Glitch. Puedes escribir el código por ti mismo, o usar los archivos de punto de inicio enlazados en las secciones superiores.
  2. +
  3. Escribe una publicación solicitando evaluacion y/o ayuda en el MDN Discourse forum Learning category. Tu publicación debería incluir: +
      +
    • Un título descriptivo como "Solicito evaluacion para la prueba de habilidad de controles HTML5 1".
    • +
    • Detalles de lo que ya has intentado, y que te gustaría que hiciéramos, por ejemplo, si estas atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que quieres que sea evaluado o por el que necesitas ayuda en un  editor en linea con capacidad de compartir (como se mencionó en el paso 1 más arriba). Esta es una buena práctica  - Es muy dificil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la tarea o página de evaluacion actual, para que podamos encontrar la pregunta con la cual necesitas ayuda.
    • +
    +
  4. +
diff --git a/files/es/learn/html/forms/prueba_tus_habilidades_colon__otros_controles/index.html b/files/es/learn/html/forms/prueba_tus_habilidades_colon__otros_controles/index.html new file mode 100644 index 0000000000..1496025a8d --- /dev/null +++ b/files/es/learn/html/forms/prueba_tus_habilidades_colon__otros_controles/index.html @@ -0,0 +1,87 @@ +--- +title: 'Prueba tus habilidades: Otros controles' +slug: 'Learn/HTML/Forms/Prueba_tus_habilidades:_Otros_controles' +translation_of: 'Learn/Forms/Test_your_skills:_Other_controls' +--- +
{{learnsidebar}}
+ +

El objetivo de esta pueba de habilidad es evaluar si has comprendido nuestro artículo Otros controles de formulario.

+ +
+

Nota: Puedes intentar resolver esta prueba en los editores interactivos más abajo, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePenjsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te atascas, pide ayuda — mira la sección Evaluación o ayuda adicional al final de esta página.

+
+ +

Otros controles 1

+ +

En nuestra primera evaluación de "Otros controles", te pediremos crear una entrada de texto de líneas múltiples.

+ +
    +
  1. Crea una entrada básica de texto de múltiples líneas.
  2. +
  3. Asócialo semánticamente con la etiqueta de "Comentario" asociado.
  4. +
  5. Define la entrada con 35 columnas y 10 filas de espacio en cual agregar comentarios.
  6. +
  7. Define para los comentatios una longitud máxima de 100 caracteres.
  8. +
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/tasks/other-controls/other-controls1.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Otros controles 2

+ +

Ahora es tiempo de implementar un menú desplegable, para permitir al usuario escoger su comida favorita de las opciones entregadas.

+ +
    +
  1. Crea tu estructura de caja básica.
  2. +
  3. Asóciala semánticamente con la etiqueta de "comentarios" entregada.
  4. +
  5. Dentro de la lista, divide las opciones en 2 subgrupos - "principales" y "meriendas".
  6. +
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/tasks/other-controls/other-controls2.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Otros controles 3

+ +

En la tarea final de esta evaluación, comenzaremos con la misma lista de opciones de comida. Sin embargo, esta vez queremos hacer las cosas de otra forma:

+ +
    +
  1. Crea una entrada de texto básica, que esté asociada semánticamente con la etiqueta entregada.
  2. +
  3. Coloca las opciones de comida en una lista que pueda ser asociada con una entrada de formulario.
  4. +
  5. Asocia la lista con tu entrada de texto, de forma que cuando escribas caracteres, cualquier opción de la lista que coincida con la secuencia de caracteres ingresada, aparezca en un listado desplegable como sugerencia de autocompletado.
  6. +
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/tasks/other-controls/other-controls3.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos que se encuentran más arriba.

+ +

Si deseas que tu trabajo sea evaluado, o estás atorado y quieres solicitar ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea con capacidad de compartir como CodePenjsFiddle, o Glitch. Puedes escribir el código por ti mismo, o usar los archivos de punto de inicio enlazados en las secciones superiores.
  2. +
  3. Escribe una publicación solicitando evaluacion y/o ayuda en el MDN Discourse forum Learning category. Tu publicación debería incluir: +
      +
    • Un título descriptivo como "Solicito evaluacion para la prueba de habilidad de Otros controles 1".
    • +
    • Detalles de lo que ya has intentado, y que te gustaría que hiciéramos, por ejemplo, si estas atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que quieres que sea evaluado o por el que necesitas ayuda en un  editor en linea con capacidad de compartir (como se mencionó en el paso 1 más arriba). Esta es una buena práctica  - Es muy dificil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la tarea o página de evaluacion actual, para que podamos encontrar la pregunta con la cual necesitas ayuda.
    • +
    +
  4. +
diff --git a/files/es/learn/html/forms/sending_and_retrieving_form_data/index.html b/files/es/learn/html/forms/sending_and_retrieving_form_data/index.html new file mode 100644 index 0000000000..d6ca2161a4 --- /dev/null +++ b/files/es/learn/html/forms/sending_and_retrieving_form_data/index.html @@ -0,0 +1,328 @@ +--- +title: Sending form data +slug: Learn/HTML/Forms/Sending_and_retrieving_form_data +translation_of: Learn/Forms/Sending_and_retrieving_form_data +--- +
{{LearnSidebar}} {{PreviousMenuNext("Aprende / HTML / Formularios / The_native_form_widgets", "Aprender / html / Formularios / Form_validation", "Aprender / html / Forms")}}
+ +

En este artículo se analiza lo que sucede cuando un usuario envía un formulario - ¿A dónde van los datos y cómo los manejamos cuando llegan allí? - También tenemos en cuenta algunos de los problemas de seguridad asociados con el envío de los datos del formulario.

+ + + + + + + + + + + + +
Requisitos previos:Conocimientos básicos de informática, una comprensión de HTML , y conocimientos básicos de HTTP y programación del lado del servidor .
Objetivo:Para entender lo que sucede cuando se envía los datos del formulario, incluyendo la obtención de una idea básica de cómo se procesan los datos en el servidor
+ +

¿A dónde van los datos?

+ +

Aquí vamos a discutir lo que ocurre con los datos cuando se envía un formulario.

+ +

Sobre la arquitectura cliente / servidor

+ +

La web se basa en una arquitectura cliente / servidor muy básica que se puede resumir de la siguiente manera: un cliente (normalmente un navegador Web) envía una petición a un servidor (la mayoría de las veces un servidor web como Apache , Nginx , IIS , Tomcat , etc.), utilizando el protocolo HTTP . El servidor responde a la solicitud utilizando el mismo protocolo.

+ +

Un esquema básico de la arquitectura cliente Web / servidor

+ +

En el lado del cliente, un formulario HTML no es más que una manera fácil de usar conveniente para configurar una petición HTTP para enviar datos a un servidor. Esto permite al usuario para proporcionar información a ser entregada en la petición HTTP.

+ +
+

Nota : Para tener una mejor idea de cómo funcionan las arquitecturas cliente-servidor, lea nuestra programación de páginas web del lado del servidor, módulo: primeros pasos. En el lado del cliente: Debes definir como envías los datos.

+
+ +

El elemento {{HTMLElement ( "form")}} define cómo se enviarán los datos. Todos sus atributos están diseñados para que pueda configurar la solicitud que se enviará cuando un usuario pulsa un botón de envío. Los dos atributos más importantes son {{htmlattrxref ( "acción", "forma")}} y {{htmlattrxref ( "método", "forma")}}.

+ +

El atributo {{htmlattrxref ( "acción", "forma")}}.

+ +

Este atributo define el lugar donde los datos se envian. Su valor debe ser una dirección URL válida. Si no se proporciona este atributo, los datos serán enviados a la dirección URL de la página que contiene el formulario.

+ +

En este ejemplo, los datos se envían a una dirección URL absoluta - http://foo.com:

+ +
<Acción del formulario = "http://foo.com">
+ +

Aquí, nosotros usamos una URL relativa - los datos se envían a una dirección URL diferente en el servidor:

+ +
<Acción del formulario = "/ somewhere_else">
+ +

Cuando se especifica sin atributos, como abajo, el {{HTMLElement ( "form")}} los datos se envían a la misma página en que la "forma" está presente :

+ +
<Form>
+ +

Muchas páginas más antiguas utilizan la siguiente notación para indicar que los datos deben ser enviados a la misma página que contiene el formulario; Esto fue necesario porque hasta HTML5, el atributo {{htmlattrxref ( "acción", "form")}} fue requerido . Esto ya no es necesario.

+ +
<Form action = "#">
+ +
+

Nota: Es posible especificar una dirección URL que utiliza el protocolo HTTPS (HTTP seguro). Al hacer esto, los datos se cifran junto con el resto de la solicitud, incluso si el propio formulario está alojado en una página insegura se accede a través de HTTPS. Por otro lado, si el formulario está alojado en una página segura, pero se especifica una dirección URL HTTP insegura con el atributo {{htmlattrxref ( "acción", "form")}} , todos los navegadores mostrarán una advertencia de seguridad para el usuario cada vez  que intenten enviar datos, ya que estos no se pueden cifrar.

+
+ +

El atributo {{htmlattrxref ( "método", "form")}}

+ +

Este atributo define cómo se envían los datos. El protocolo HTTP proporciona varias formas de realizar una solicitud; Los datos del formulario HTML se pueden transmitir a través de un número de diferentes queridos, los más comunes de los cuales son el método GET y el método POST.

+ +

Para entender la diferencia entre estos dos métodos, vamos a dar un paso atrás y examinar cómo funciona HTTP. Cada vez que desee llegar a un recurso en la Web, el navegador envía una petición a una URL. Una petición HTTP consta de dos partes: un encabezado que contiene un conjunto de metadatos mundial sobre las capacidades del navegador, y un cuerpo que puede contener la información necesaria paraque el servidor pueda procesar la petición específica.

+ +
El método GET
+ +

El método GET es  utilizado por el navegador para pedir al servidor que se envíe de vuelta un recurso dado: "Hey servidor, quiero conseguir este recurso." En este caso, el navegador envía un cuerpo vacío. Debido a que el cuerpo está vacío, si un formulario se envía utilizando este método, los datos enviados al servidor se anexan a la URL.

+ +

Considere la siguiente forma:

+ +
<form action="http://foo.com" method="get">
+  <div>
+    <label for="decir"> ¿Qué saludo quiere decir? </label>
+    <input name="decir" id="decir" value="Hola">
+  </div>
+  <div>
+    <label for="para"> ¿A quién se lo quiere decir? </label>
+    <input name="para" value="mamá">
+  </div>
+  <div>
+    <button> Botón enviar mis saludos </ button>
+  </div>
+</form>
+ +

Dado que el método GETha conseguido el recurso, verá en la URL lo siguiente en la barra de direcciones del navegador www.foo.com/?say=Hi&to=Mom  cuando se envía el formulario.

+ +

Los datos se añaden a la URL como una serie de pares de nombre / valor. Después que la dirección web URL ha terminado, se incluye un signo de interrogación ( ?) seguido de los pares de nombre / valor, cada uno separado por un signo ( &). En este caso estamos pasando dos piezas de datos en el servidor:

+ + + +

La solicitud HTTP se ve así:

+ +
GET /? = Decir Hola & a = mamá HTTP / 1.1
+Anfitrión: foo.com
+ +
+

Nota : Puede encontrar este ejemplo en GitHub - ver llegar-method.html ( verlo en directo también ).

+
+ +
El método POST
+ +

El POSTmétodo es un poco diferente. Es el método que el navegador utiliza para comunicarse con el servidor cuando se pide una respuesta que tenga en cuenta los datos proporcionados en el cuerpo de la petición HTTP: "Hey servidor, echa un vistazo a estos datos y envíame de vuelta un resultado apropiado." Si un formulario se envía utilizando este método, los datos se anexan al cuerpo de la petición HTTP.

+ +

Veamos un ejemplo - se trata de algo similar a como se vió en el método GETdel apartado anterior, pero con el {{htmlattrxref ( "método", "form")}} atributo establecido post.

+ +
<Form action = "http://foo.com" method = "post">
+  <Div>
+    <Label for = "dice"> Lo saludo qué quiere decir? </ Label>
+    <Input name = "decir" id = "decir" value = "Hola">
+  </ Div>
+  <Div>
+    <Label for = "para"> ¿Quién usted quiere decir que a? </ Label>
+    <Input name = "a" value = "mamá">
+  </ Div>
+  <Div>
+    <> Botón enviar mis saludos </ botón>
+  </ Div>
+</ Form>
+ +

Cuando el formulario se envía mediante el método POST, no se obtienen los datos adjuntos en la dirección URL, y la solicitud HTTP se parece a esto y los datos son incluidos en el cuerpo de la petición en su lugar:

+ +
POST / HTTP/1.1
+Anfitrión: foo.com
+Content-Type: application / x-www-form-urlencoded
+Content-Length: 13
+
+decir = Hi & a = mamá
+ +

La cabecera Content-Length indica el tamaño del cuerpo, y la cabecera Content-Type indica el tipo de recurso que se envía al servidor. Discutiremos estas cabeceras más adelante.

+ +
+

Nota : Puede encontrar este ejemplo en GitHub - ver post-method.html ( verlo en directo también ).

+
+ +

Visualización de peticiones HTTP

+ +

Las peticiones HTTP nunca se muestran al usuario (si quieres verlos, es necesario utilizar herramientas como el Monitor de red Firefox o las herramientas de desarrollo de Chrome ). A modo de ejemplo, los datos del formulario se muestran a continuación en la pestaña de Chrome red:

+ +

+ +

Lo único que se muestra al usuario es la dirección URL llamada. Como mencionamos anteriormente, con una peticiónGET del usuario,se verán los datos en su barra de direcciones, pero con una petición POST no será de esta manera. Esto puede ser muy importante por dos razones:

+ +
    +
  1. Si necesita enviar una contraseña (o cualquier otra pieza sensible de los datos), nunca utilice el métodoGET o se arriesga a mostrar en la barra de direcciones, lo que sería muy inseguro.
  2. +
  3. Si necesita enviar una gran cantidad de datos, el método POSt es preferible debido a que algunos navegadores limitan los tamaños de las direcciones URL. Además, muchos servidores limitan la longitud de las URL que aceptan.
  4. +
+ +

En el lado  Servidor: la recuperación de los datos

+ +

Sea cual sea el método HTTP que elija, el servidor recibe una cadena que será analizada con el fin de obtener los datos como una lista de pares clave / valor. La forma de acceder a esta lista depende de la plataforma de desarrollo que use y de las estructuras específicas que pueda estar usando con él. La tecnología se utiliza también determina cómo se manejan claves duplicadas; A menudo,se da prioridad al valor recibido más recientemente para una clave dada .

+ +

Ejemplo: PHP Raw

+ +

PHP ofrece algunos objetos globales para acceder a los datos. Suponiendo que usted ha utilizado el métodoPOST, el siguiente ejemplo sólo toma los datos y lo muestra al usuario. Por supuesto, lo que se hace con los datos depende de usted. Es posible visualizarlos, almacenarlos en una base de datos, enviarlos por correo electrónico, o procesarlos de alguna otra manera.

+ +
<? Php
+  // La variable global $ _POST que permite acceder a los datos enviados con el método POST por su nombre
+  // Para acceder a los datos enviados con el método GET, puede usar $ _GET
+  $ = Decir htmlspecialchars ($ _POST [ 'decir']);
+  $ A = htmlspecialchars ($ _POST [ 'a']);
+
+  echo $ digamos, '', $ a;
+?>
+ +

Este ejemplo muestra una página con los datos que enviamos. Esto se puede ver en acción en nuestro archivo ejemplo php-example.html - que contiene un ejemplo similar en forma como el que hemos visto antes, con un methodcon parámetro posty un action con parámetro php-example.php Cuando se envía, envía los datos del formulario al script php-ejemplo.php , que contiene el código de PHP que se ha visto en el bloque anterior. Cuando se ejecuta este código, la salida en el navegador es Hi Mom.

+ +

+ +
+

Nota : Este ejemplo no funcionará cuando se carga en un navegador localmente - los navegadores no pueden interpretar  código PHP, por lo que cuando se envía el formulario en el navegador sólo  se puede ofrecer la descarga del archivo PHP para usted. Para conseguir que funcione, es necesario ejecutar el ejemplo a través de un servidor PHP de algún tipo. Buenas opciones para probar PHP locales son MAMP (Mac y Windows) y AMPPS (Mac, Windows, Linux).

+
+ +

Ejemplo: Python

+ +

Este ejemplo muestra como se puede utilizar Python para hacer la misma cosa - mostrar los datos presentados en una página web. Se utiliza el framework Flask para la prestación de las plantillas, el manejo de la presentación de datos de formulario, etc (ver python-example.py ).

+ +
from flask import Flask, render_template, request
+app = Flask(__name__)
+
+@app.route('/', methods=['GET', 'POST'])
+def form():
+    return render_template('form.html')
+
+@app.route('/hello', methods=['GET', 'POST'])
+def hello():
+    return render_template('greeting.html', say=request.form['say'], to=request.form['to'])
+
+if __name__ == "__main__":
+    app.run()
+ +

Las dos plantillas de referencia en el código anterior son los siguientes:

+ + + +
+

Nota : Una vez más, este código no funcionará si sólo intenta cargarlo en un navegador directamente. Python funciona un poco diferente a PHP - Para ejecutar este código local que necesita para instalar Python / PIP , a continuación, instalar el frasco utilizando pip3 install flask. En este punto, usted debe ser capaz de ejecutar el ejemplo utilizando python3 python-example.py, a continuación, deberá navegar a localhost:5000en su barra de direcciones.

+
+ +

Otros lenguajes y frameworks

+ +

Hay muchas otras tecnologías del lado del servidor que puede utilizar para el manejo de formularios, incluyendo Perl , Java , .Net , Rubí , etc. Sólo tiene que elegir el que más le guste. Dicho esto, vale la pena señalar que es muy raro de usar estas tecnologías directamente porque esto puede ser complicado. Es más común el uso de uno de los muchos marcos de trabajo para un manejo más fácil del código, tales como:

+ + + +

Vale la pena señalar que incluso el uso de estos marcos, trabajar con formularios no es necesariamente fácil . Pero es mucho más fácil que tratar de escribir toda la funcionalidad  a partir de cero, además, le ahorrará mucho tiempo.

+ +
+

Nota : Está más allá del alcance de este artículo para enseñarle cualquier lenguaje del lado del servidor o marcos de trabajo. Los enlaces de arriba le dará un poco de ayuda,en caso de que desee aprender.

+
+ +

Un caso especial: el envío de archivos

+ +

El envío de archivos con formularios HTML es un caso especial. Los archivos son datos binarios - o considerados como tal - mientras que todos los demás datos son datos de texto. Debido a que HTTP es un protocolo de texto, existen requisitos especiales para el manejo de datos binarios.

+ +

El {{htmlattrxref ( "enctype", "form")}} atributo

+ +

Este atributo le permite especificar el valor de la cabecera Content-Type HTTP incluido en la solicitud que se genera cuando se envía el formulario. Esta cabecera es muy importante porque le dice al servidor qué tipo de datos se está enviando. Por defecto, su valor es application/x-www-form-urlencoded. En términos humanos, esto significa: "Estos son datos de formulario que han sido codificados dentro de los parámetros de la URL."

+ +

Si desea enviar archivos, es necesario tomar tres pasos adicionales:

+ + + +

Por ejemplo:

+ +
<Form method = "post" enctype = "multipart / form-data">
+  <Div>
+    <Label for = "archivo"> ​​Elija un archivo </ label>
+    <Input type = "file" id = "file" name = "myFile">
+  </ Div>
+  <Div>
+    <> Botón Enviar el archivo </ botón>
+  </ Div>
+</ Form>
+ +
+

Nota: Algunos navegadores son compatibles con la {{htmlattrxref ( "múltiple", "input")}} atributo en el elemento {{HTMLElement ( "input")}}, lo que permite elegir más de un archivo  para subir con un único elemento <input> . Cómo el servidor gestiona los archivos realmente depende de la tecnología utilizada en el servidor. Como se mencionó anteriormente, el uso de un marco le hará la vida mucho más fácil.

+
+ +
+

Advertencia: Muchos servidores están configurados con un límite de tamaño para los archivos y las peticiones HTTP con el fin de prevenir el abuso. Es importante comprobar este límite con el administrador del servidor antes de enviar un archivo.

+
+ +

Precauciones de seguridad comunes

+ +

Cada vez que envíe datos a un servidor, debe tener en cuenta la seguridad de sus formularios HTML que son con mucho, los vectores de ataque más comunes (en lugares donde ocurren los ataques contra servidores). Los problemas nunca vienen de los formulariosHTML mismos - sino que proceden de cómo el servidor maneja los datos.

+ +

Dependiendo de lo que estés haciendo, hay algunos problemas de seguridad muy conocidos con los que te enfrentarás:

+ +

XSS y CSRF

+ +

Cross-Site Scripting (XSS) y Cross-Site Request Falsification (CSRF) son tipos comunes de ataques que se producen cuando se muestran los datos enviados por un usuario y que son devueltos a otro usuario para otro uso.

+ +

XSS permite a los atacantes inyectar secuencias de comandos del lado del cliente en páginas Web visitadas por otros usuarios. Una vulnerabilidad de secuencias de comandos entre sitios, puede ser utilizada por los atacantes para eludir los controles de acceso, como la política del mismo origen . El efecto de estos ataques pueden ir desde una pequeña molestia a un riesgo de seguridad.

+ +

Los ataques CSRF son similares a los ataques XSS porque comienzan de la misma manera - mediante la inyección de comandos de cliente en páginas Web - pero su objetivo es diferente. Los atacantes CSRF tratan de escalar privilegios  de un usuario de mayores privilegios (por ejemplo, un administrador de sitio) para realizar una acción que no deberían ser capaces de hacer (por ejemplo, el envío de datos a un usuario no fiable).

+ +

Los ataques XSS explotan la confianza depositada a un usuario de un sitio web, mientras que los ataques CSRF abusan de la confianza que un sitio web ofrece para sus usuarios.

+ +

Para evitar estos ataques, siempre se deben comprobar los datos que un usuario envía a su servidor y (si es necesario mostrarlos) trate de no mostrar el contenido HTML provisto por el usuario. En su lugar, se deben procesar los datos proporcionados por el usuario para no mostrarlos al pie de la letra. Casi todos los marcos de trabajo (frameworks) en el mercado hoy implementan un filtro mínimo que eliminan el código HTML {{HTMLElement ( "script")}}, {{HTMLElement ( "iframe")}} y {{HTMLElement ( "objeto")}} si fuesen enviados por cualquier usuario. Esto ayuda a mitigar el riesgo, pero no necesariamente lo erradica.

+ +

Inyección SQL

+ +

La inyección de SQL es un tipo de ataque que intenta realizar acciones en una base de datos utilizada por el sitio web de destino. Esto normalmente implica el envío de una petición SQL con la esperanza de que el servidor la ejecutará (por lo general cuando el servidor de aplicaciones intenta almacenar los datos enviados por un usuario). Esto es en realidad uno de los principales vectores de ataque contra los sitios web  .

+ +

Las consecuencias pueden ser terribles, que van desde la pérdida de datos o hasta que los ataques  tomen el control de la infraestructura de todo el sitio web mediante el uso de una escalada de privilegios. Esta es una amenaza muy seria y nunca debe almacenar los datos enviados por un usuario sin realizar alguna sanitización (por ejemplo, mediante el uso mysql_real_escape_string()de una infraestructura de PHP / MySQL).

+ +

Inyección de cabecera HTTP y la inyección de correo electrónico

+ +

Este tipo de ataques pueden ocurrir cuando su aplicación se basa cabeceras HTTP o mensajes de correo electrónico basado en la entrada de datos por un usuario en un formulario. Estos no dañan directamente su servidor o afectan a sus usuarios, pero son una puerta abierta a problemas más profundos tales como el secuestro de sesión o ataques de phishing.

+ +

Estos ataques son en su mayoría en silencio, y pueden volver a su servidor en un zombi .

+ +

Sea paranoico: Nunca confíe en sus usuarios

+ +

Entonces, ¿cómo se lucha contra estas amenazas? Este es un tema mucho más allá de esta guía, pero hay algunas reglas a tener en cuenta. La regla más importante es: nunca vuelva a confiar en sus usuarios, incluyáse a sí mismo; incluso un usuario de confianza podría haber sido secuestrado.

+ +

Todos los datos que vienen a su servidor deben comprobarse y ser desinfectados. Siempre. Sin excepción.

+ + + +

Debería evitar muchos o  la mayoría de estos problemas, si sigue estas tres reglas, pero siempre es una buena idea  obtener una revisión de seguridad realizada por una tercera parte competente. No asuma que usted ha visto todos los posibles problemas.

+ +
+

Nota : La seguridad del sitio web el artículo de nuestro lado del servidor tema de aprendizaje analiza las amenazas anteriores y las posibles soluciones con más detalle.

+
+ +

Conclusión

+ +

Como se puede ver, el envío de los datos del formulario es fácil, pero asegurar una aplicación puede ser complicado. Sólo recuerde que un desarrollador de aplicaciones para usuario no es el que debe definir el modelo de seguridad de los datos. Sí, como veremos, es posible realizar la validación de los datos del lado del cliente , pero el servidor no puede confiar en esta validación porque no tiene manera de saber realmente lo que  sucede en el lado del cliente.

+ +

Ver también

+ +

Si desea obtener más información sobre la seguridad de una aplicación web, se puede excavar en estos recursos:

+ + + +

{{PreviousMenuNext ( "Aprende / html / Formularios / The_native_form_widgets", "Saber / html / Formularios / Form_validation", "Aprender / html / Forms")}}

diff --git a/files/es/learn/html/forms/styling_html_forms/index.html b/files/es/learn/html/forms/styling_html_forms/index.html new file mode 100644 index 0000000000..26b4173ee8 --- /dev/null +++ b/files/es/learn/html/forms/styling_html_forms/index.html @@ -0,0 +1,345 @@ +--- +title: Estilizando formularios HTML +slug: Learn/HTML/Forms/Styling_HTML_forms +translation_of: Learn/Forms/Styling_web_forms +--- +

En este artículo aprenderemos como utilizar CSS con formularios HTML  para hacerlos más atractivos. Aunque parezca extraño, esto es algo que puede llegar a ser complicado. Por razones históricas y técnicas, los widgets de formulario no suelen llevarse bien con CSS. Por este motivo, muchos desarrolladores prefieren construir sus propios widgets para tener el control de su aspecto en vez de utilizar los nativos. De todas formas, con los modernos navegadores, los diseñadores web cada vez tienen  más control sobre el diseño de los elementos de formulario. Vamos a profundizar en esto.

+ +

¿Porqué es tan difícil aplicar estilos a formularios con CSS?

+ +

En los principios de la Web —allá por1995—se añadieron los controles de formulario en la 2ª especificación HTML. Debido a la complejidad de los widgets de formulario, los implementadores prefirieron dejar que el sistema operativo subyacente se encargara de su manejo y presentación.

+ +

Pocos años después,  se creó CSS y lo que era una necesidad técnica— es decir, el uso de widgets nativos para implementar controles de formulario—empezó a requerir estilizado. Y en los primeros días de CSS, el estilizado de formularios no fué una prioridad.

+ +

Por otra parte, como los usuarios estaban acostumbrados a la apariencia visual de sus plataformas respectivas, los fabricantes de navegadores fueron reacios a hacer que los controles de formularios pudieran recibir estilos.

+ +

Hoy en día, ni siquiera uno solo de los navegadores actuales implementa completamente a CSS 2.1. Afortunadamente, con el tiempo, los fabricantes de navegadores han ido mejorado su soporte a CSS para los elementos de formulario e, incluso considerando que su usabilidad tiene mala reputación, actualmente, ya se puede usar CSS para estilizar formularios HTML.

+ +

No todos los widgets se crean igual con CSS

+ +

Actualmente aun se encuentran dificultades cuando se utiliza CSS con formularios; estos problemas se pueden dividir en tres categorías.

+ +

El bueno

+ +

A algunos elementos se les puede dar estilo con pocos o ningún problema independientemente de la plataforma. Entre estos se incluyen los siguientes elementos estructurales:

+ +
    +
  1. {{HTMLElement("form")}}
  2. +
  3. {{HTMLElement("fieldset")}}
  4. +
  5. {{HTMLElement("label")}}
  6. +
  7. <output>
  8. +
+ +

Esto también incluye todos los campos de texto (tanto los de línea simple como los de línea múltiple) y los botones.

+ +
    +
+ +

El malo

+ +

Hay otros elementos a los que raramente se les puede aplicar estilos y pueden llegar a requerir  técnicas complejas y ocasionalmente necesitan conocimientos avanzados de CSS3.

+ +

Entre estos se incluyen el elemento {{HTMLElement("legend")}} ; que no puede posicionarse adecuadamente en todas las plataformas.  Los elementos checkbox y los botones de radio no permiten que se le apliquen estilos directamente;  de todas formas, gracias a CSS3 esto puede soslayarse. Al contenido de  placeholder no se le puede aplicar estilo de ninguna forma convencional; sin embargo, todos los navegadores que lo implementan  también implementan pseudo-elementos o pseudo-clases propietarias que permiten darles estilo.

+ +

Veremos como trabajar con estos casos específicos en el artículo Advanced styling for HTML forms.

+ +

El feo

+ +

En algunos elementos, simplemente no se puede utilizar CSS. Estos son todos los elementos avanzados de interface de usuario tales como los controles range, color, o date, e igualmente pasa con los widgets desplegables como select, option, optgropup y datalist. Respecto al selector de archivos, es bien sabido que no puede aplicarse estilo en absoluto. Los nuevos elementos progress y meter también caen dentro de esta categoría.

+ +

El principal problema con todos estos widgets viene de que todos ellos tienen una estructura muy compleja y CSS no es lo suficientemente expresivo para estilizar cada una de sus sutiles partes. Si lo que se quiere es personalizar estos widgets se deberá recurrir a javaScript para construir un árbol DOM que te permita acceder a ellos. Para aprender como conseguirlo mirar en el artículo How to build custom form widgets.

+ +

Estilizado básico

+ +

Aplicar estilos a elementos que son fáciles de estilizar con CSS, no debería suponer ninguna dificultad ya que básicamente se comportan como cualquier otro elemento HTML. De todas formas, el agente de usuario de estilos para cada navegador puede mostrar pequeñas inconsistencias por lo que a continuación daremos algunos trucos para ayudar a aplicar estilos más cómodamente.

+ +

Campos de búsqueda

+ +

Las cajas de búsqueda son el único tipo de campo de texto que pueden ofrecer más dificultad al aplicar estilos. En los navegadores basados en webkit (Chrome, Safari, etc.) se debe lidiar con la propiedad -webkit-. Discutiremos esta propiedad más tarde en el artículo: Advanced styling for HTML forms.

+ +

Ejemplo

+ +
<form>
+  <input type="search">
+</form>
+
+ +
input[type=search] {
+  border: 1px dotted #999;
+  border-radius: 0;
+
+  -webkit-appearance: none;
+}
+ +

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

+ +

En esta captura de pantalla pueden verse dos campos de búsqueda en Chrome, ambos campos tienen definido el borde como en nuestro ejemplo, pero el primero no utiliza -webkit- mientras que el segundo si lo hace con -webkit-appearance:none. Las diferencias son evidentes.

+ +

Fuentes y texto

+ +

Las fuentes y capacidades de texto de CSS  se pueden utilizar sin problemas en cualquier widget (y sí, se puede utilizar @font-face en formularios). De todas formas, el comportamiento de los navegadores no es siempre consistente. Por defecto, algunos widgets no heredan font-family ni font-size de sus antecesores. Y muchos navegadores utilizan la apariencia por defecto. Para mantener la coherencia de los formularios con el resto de elementos se deben añadir las siguientes reglas a la hoja de estilos:

+ +
button, input, select, textarea {
+  font-family : inherit;
+  font-size   : 100%;
+}
+ +

La siguiente captura de pantalla muestra estas incosistencias; a la izquierda la apariencia por defecto en Firefox sobre Mac OS X, usando las fuentes por defecto de la plataforma. A la derecha los mismos elementos aplicando nuestras reglas de armonización de fuentes.

+ +

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

+ +

Hay muchas controversia sobre si los formularios tienen mejor aspecto usando los estilos por defecto del sistema o usando estilos personalizados que coincidan con el resto del contenido. Como diseñador del sitio o aplicación Web esta decisión  es suya.

+ +

Modelo de cajas

+ +

Todos los campos de texto tienen soporte completo para las propiedades relacionadas con el modelo de cajas de CSS (width, height, padding, margin y border). Igual que antes, los navegadores se remiten a los estilos por defecto del sistema cuando muestran estos widgets. A cada cual te corresponde el como combinarlos dentro del resto de contenido. Si  se quieres mantener el aspecto nativo de los widgets, entonces hay que afrontar pequeñas inconsistencias de tamaño.

+ +

Esto es porque cada widget tiene sus propias reglas para el orden, margen y padding. Por lo que si quieres darle el mismo tamaño a varios widgets diferentes se debe usar la propiedad box-sizing: 

+ +
input, textarea, select, button {
+  width : 150px;
+  margin: 0;
+
+  -webkit-box-sizing: border-box; /* For legacy WebKit based browsers */
+     -moz-box-sizing: border-box; /* For legacy (Firefox <29) Gecko based browsers */
+          box-sizing: border-box;
+}
+ +

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

+ +

En la captura de pantalla de arriba, la columna la izquierda es sin utilizar box-sizing, mientras que la de la derecha usa esta propiedad con el valor border-box. Obsérvese cómo esto permite asegurar que todos los elementos ocupan la misma cantidad de espacio, independientemente de las reglas por defecto de la plataforma.

+ +

Posicionado

+ +

El posicionado de formularios HTML no es generalmente  un problema; sin embargo, hay dos elementos a los que prestar una especial atención:

+ +

legend

+ +

El elemento legend no tiene problemas de estilizado a excepción de las reglas de posición. En los navegadores el elemento legend se posiciona encima del borde superior de su antecesor fieldset. No existe ninguna posibilidad de colocarlo dentro del flujo HTML más allá del borde superior. Sin embargo se puede posicionar de forma relativa o absoluta mediante la propiedad position. En cualquier caso sigue siendo parte del borde de fieldset.

+ +

Debido a que el elemento legend es muy importante por razones de accesibilidad (esto es lo que leen las tecnologías de asistencia como parte de las etiquetas de cada elemento de formulario dentro del fieldset), bastante menudo se empareja con un título que se oculta pero siendo aun accesible, de la forma siguiente:

+ +
HTML
+ +
<fieldset>
+  <legend>Hi!</legend>
+  <h1>Hello</h1>
+</fieldset>
+ +
CSS
+ +
legend {
+  width: 1px;
+  height: 1px;
+  overflow: hidden;
+}
+ +

textarea

+ +

Por defecto, todos los navegadores consideran el elemento textarea como un inline block alineado con la línea base del texto. Esto es algo que raramente es lo que en realidad se quiere. Para convertir este elemento de un inline-block a uno tipo block, se realiza bastante fácilmente utilizando la propiedad display. Si lo que quieres es utilizarlo inline, es corriente cambiar la alineación vertical: 

+ +
textarea {
+  vertical-align: top;
+}
+ +

Ejemplo

+ +

Vamos a ver un ejemplo de como aplicar estilo a un formulario HTML. Esto nos ayudará a tener las ideas más claras. A continuación construiremos el siguiente formulario de contacto de esta postal:

+ +

This is what we want to achieve with HTML and CSS

+ +

HTML

+ +

El HTML  incluye poco más de lo que se utiliza en el primer artículo de esta guía; apenas el título y algún ID más.

+ +
<form>
+  <h1>to: Mozilla</h1>
+
+  <div id="from">
+    <label for="name">from:</label>
+    <input type="text" id="name" name="user_name">
+  </div>
+
+  <div id="reply">
+    <label for="mail">reply:</label>
+    <input type="email" id="mail" name="user_email">
+  </div>
+
+  <div id="message">
+    <label for="msg">Your message:</label>
+    <textarea id="msg" name="user_message"></textarea>
+  </div>
+
+  <div class="button">
+    <button type="submit">Send your message</button>
+  </div>
+</form>
+ +

CSS

+ +

¿Aqui es donde empieza la diversión! Antes de empezar a codificar, necesitamos tres elementos adicionales:

+ +
    +
  1. El fondo de la postal
  2. +
  3. Una fuente tipográfica: la "Secret Typewriter" de fontsquirrel.com
  4. +
  5. Una fuente manuscrita: la "Journal" fde fontsquirrel.com
  6. +
+ +

Ahora podemos repasar el código. Primero preparamos las bases definiendo las reglas  @font-face y los elementos básicos de <body> y <form> 

+ +
@font-face{
+  font-family : "handwriting";
+
+  src : url('journal.eot');
+  src : url('journal.eot?') format('eot'),
+        url('journal.woff') format('woff'),
+        url('journal.ttf') format('truetype');
+}
+
+@font-face{
+  font-family : "typewriter";
+
+  src : url('veteran_typewriter.eot');
+  src : url('veteran_typewriter.eot?') format('eot'),
+        url('veteran_typewriter.woff') format('woff'),
+        url('veteran_typewriter.ttf') format('truetype');
+}
+
+body {
+  font  : 21px sans-serif;
+
+  padding : 2em;
+  margin  : 0;
+
+  background : #222;
+}
+
+form {
+  position: relative;
+
+  width  : 740px;
+  height : 498px;
+  margin : 0 auto;
+
+  background: #FFF url(background.jpg);
+}
+ +

Ahora podemos posicionar los elementos, incluidos el título y los elementos del formulario.

+ +
h1 {
+  position : absolute;
+  left : 415px;
+  top  : 185px;
+
+  font : 1em "typewriter", sans-serif;
+}
+
+#from {
+  position: absolute;
+  left : 398px;
+  top  : 235px;
+}
+
+#reply {
+  position: absolute;
+  left : 390px;
+  top  : 285px;
+}
+
+#message {
+  position: absolute;
+  left : 20px;
+  top  : 70px;
+}
+ +

Aquí es donde empezamos a trabajar los propios elementos. Primero, nos aseguramos que los elementos  <label> reciben la fuente correcta.

+ +
label {
+  font : .8em "typewriter", sans-serif;
+}
+ +

Los campos de texto necesitan algunas reglas comunes. Dicho simplemente, le quitamos bordes y fondos y redefinimos el padding y margin.

+ +
input, textarea {
+  font    : .9em/1.5em "handwriting", sans-serif;
+
+  border  : none;
+  padding : 0 10px;
+  margin  : 0;
+  width   : 240px;
+
+  background: none;
+}
+ +

Cuando uno de estos campos recibe el foco, vamos a resaltarlo con un fondo transparente gris claro. Tome nota de que es importante añadir la propiedad  outline  para quitar el resaltado de enfoque añadido por defecto por algunos navegadores.

+ +
input:focus, textarea:focus {
+  background   : rgba(0,0,0,.1);
+  border-radius: 5px;
+  outline      : none;
+}
+ +

Ahora que nuestros campos de texto están terminados, necesitamos ajustar como se muestran los campos de simple y múltiple línea para que coincidan, ya que lo normal es que por defecto no se vean igual.

+ +

El campo de línea simple requiere de algunos trucos para que se vean bien en Internet Explorer. Internet Explorer no define la altura de los campos basándose en la altura natural de la fuente (lo cual es el comportamiento normal del resto de navegadores). Para corregir esto necesitamos añadir explícitamente la altura a los campos de la siguiente forma:

+ +
input {
+    height: 2.5em; /* for IE */
+    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
+}
+ +

Los elementos <textarea> se muestran por defecto como bloques, Las dos cosas importantes aquí son las propiedades  resize y overflow. Ya que nuestro diseño es de tamaño fijo, utilizaremos la propiedad resize para impedir que el usuario pueda cambiar el tamaño de los campos multilínea. La propiedad  overflow  se utiliza para que el campo se muestre de forma más consistente a través de diversos navegadores; algunos de ellos ponen por defecto esta propiedad en auto, pero en nuestro caso, es mejor asegurarse de que todos estén en auto.

+ +
textarea {
+  display : block;
+
+  padding : 10px;
+  margin  : 10px 0 0 -10px;
+  width   : 340px;
+  height  : 360px;
+
+  resize  : none;
+  overflow: auto;
+}
+ +

El elemento <button> se acomoda muy bien a CSS; se puede hacer lo que se quiera con el, ¡incluso utilizando pseudo-elementos!

+ +
button {
+  position     : absolute;
+  left         : 440px;
+  top          : 360px;
+
+  padding      : 5px;
+
+  font         : bold .6em sans-serif;
+  border       : 2px solid #333;
+  border-radius: 5px;
+  background   : none;
+
+  cursor       : pointer;
+
+-webkit-transform: rotate(-1.5deg);
+   -moz-transform: rotate(-1.5deg);
+    -ms-transform: rotate(-1.5deg);
+     -o-transform: rotate(-1.5deg);
+        transform: rotate(-1.5deg);
+}
+
+button:after {
+  content: " >>>";
+}
+
+button:hover,
+button:focus {
+  outline   : none;
+  background: #000;
+  color   : #FFF;
+}
+ +

Y ¡listo! Sientase libre de probarlo usted mismo; como comprobará ¡esto funciona!

+ +

Conclusión

+ +

Como puede verse, mientras que queramos construir formularios solo con campos de texto y botones, es sencillo aplicarles estilos con CSS. Si desea saber más pequeños trucos de CSS que le hagan más fácil la vida al trabajar con formularios, echele un vistazo a la parte de formularios de the normalize.css project.

+ +

En el próximo artículo, veremos como manejar widgets de formulario de la categoría de "el malo" y "el feo".

diff --git a/files/es/learn/html/forms/the_native_form_widgets/index.html b/files/es/learn/html/forms/the_native_form_widgets/index.html new file mode 100644 index 0000000000..c8a2651837 --- /dev/null +++ b/files/es/learn/html/forms/the_native_form_widgets/index.html @@ -0,0 +1,326 @@ +--- +title: Controles de formulario originales +slug: Learn/HTML/Forms/The_native_form_widgets +translation_of: Learn/Forms/Basic_native_form_controls +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Forms/How_to_structure_an_HTML_form", "Learn/Forms/HTML5_input_types", "Learn/Forms")}}
+ +

En el artículo anterior, marcamos un ejemplo de formulario web funcional, presentamos algunos controles de formulario y elementos estructurales comunes, y nos centramos en las mejores prácticas de accesibilidad. A continuación, veremos con detalle las funciones de los diferentes controles de formulario, o widgets, y estudiaremos todas las diferentes opciones de que se dispone para la recopilación de diferentes tipos de datos. En este artículo en particular, veremos el conjunto original de controles de formulario, disponible en todos los navegadores desde los primeros días de la web.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática y de lenguaje HTML.
Objetivo:Comprender en detalle el conjunto original de controles de formulario originales disponibles en los navegadores para la recopilación de datos y su implementación con HTML.
+ +

Ya conoces algunos elementos de formulario, incluidos {{HTMLelement ('form')}}, {{HTMLelement ('fieldset')}}, {{HTMLelement ('legend')}}, {{HTMLelement ('textarea' )}}, {{HTMLelement ('label')}}, {{HTMLelement ('button')}} y {{HTMLelement ('input')}}. Este artículo expone:

+ + + +
+

Nota: Las características que se consideran en este artículo son compatibles con todos los navegadores, lo que no es el caso para todos los controles de formulario. En los próximos dos artículos vamos a exponer los controles de formulario que se han añadido a HTML5 más recientemente. Si quieres una referencia más avanzada, consulta nuestra referencia a elementos de formulario HTML, y en particular nuestra extensa referencia a tipos <input>.

+
+ +

Campos de entrada de texto

+ +

Los campos de texto {{htmlelement ("input")}} son los controles de formulario más básicos. Son un modo muy cómodo de permitir al usuario introducir cualquier tipo de datos, y ya hemos visto algunos ejemplos sencillos.

+ +
+

Nota: Los campos de texto de los formularios HTML son controles de entrada de texto sencillos sin formato. Esto significa que no puedes usarlos para aplicar una edición enriquecida (negrita, cursiva, etc.). Todos los controles de formulario que encuentres con texto enriquecido son controles de formulario personalizados creados con HTML, CSS y JavaScript.

+
+ +

Todos los controles de texto básicos comparten algunos comportamientos comunes:

+ + + +
+

Nota: El elemento {{htmlelement ("input")}} es único entre los elementos HTML porque puede tomar muchas formas diferentes según el valor de su atributo. Se utiliza para crear la mayoría de los tipos de controles de formulario, que incluyen campos de texto de una sola línea, controles para la fecha y la hora, controles sin introducción de texto, como casillas de verificación, botones de opción y selectores de color, y botones.

+
+ +

Campos de texto de una sola línea

+ +

Un campo de texto de una sola línea se crea utilizando un elemento {{HTMLElement ("input")}} cuyo valor de atributo {{htmlattrxref ("type","input")}} se establece en text, u omitiendo por completo el atributo {{htmlattrxref ( "type","input")}} (text es el valor predeterminado). El valor text de este atributo también es el valor alternativo si el navegador no reconoce el valor que has especificado para el atributo {{htmlattrxref ("type","input")}} (por ejemplo, si especificas type="color" y el navegador no está dotado en origen de un control de selección de colores).

+ +
+

Nota: Puedes encontrar ejemplos de todos los tipos de campo de texto de una sola línea en GitHub en single-line-text-fields.html (o consultarlo en vivo).

+
+ +

Aquí hay un ejemplo básico de campo de texto de una sola línea:

+ +
<input type="text" id="comment" name="comment" value="I'm a text field">
+ +

Los campos de texto de una sola línea solo tienen una restricción verdadera: si escribes el texto con saltos de línea, el navegador elimina esos saltos de línea antes de enviar los datos al servidor.

+ +

La captura de pantalla siguiente muestra los tipos de entrada de texto predeterminado, activo (con el foco) y deshabilitado en Firefox 71 y Safari en macOS y en Chrome 79 y Edge 18 en Windows 10.

+ +

Captura de pantalla del atributo deshabilitado y predeterminado: estilo para  una entrada de texto activa (con el foco) en Firefox, Safari, Chrome y Edge.

+ +
+

Nota: HTML5 ha mejorado el campo de texto básico original de una sola línea al añadir valores especiales para el atributo {{htmlattrxref ("type", "input")}} que imponen restricciones de validación específicas y otras características, por ejemplo, específicas para introducir direcciones URL o números. Los expondremos en el artículo siguiente: Los tipos de entrada en HTML5.

+
+ +

Campo de contraseña

+ +

Uno de los tipos de entrada originales era el tipo de campo de texto password:

+ +
<input type="password" id="pwd" name="pwd">
+ +

El valor de la contraseña no añade restricciones especiales al texto que se introduce, pero oculta el valor que se introduce en el campo (por ejemplo, con puntos o asteriscos) para impedir que otros puedan leerlo.

+ +

Ten en cuenta que esto es solo una función de interfaz de usuario; a menos que envíes tu formulario en modo seguro, se enviará como texto plano, lo que es malo desde el punto de vista de la seguridad porque alguien con malas intenciones podría interceptar tus datos y robar tus contraseñas, datos de tarjetas de crédito o cualquier otra cosa que hayas enviado. La mejor manera de proteger a los usuarios de esto es alojar cualquier página que contenga formularios en una ubicación de conexión segura (es decir, en una dirección https://), de modo que los datos se cifren antes de enviarse.

+ +

Los navegadores reconocen las implicaciones de seguridad de enviar datos de formulario por una conexión insegura y disponen de mensajes de advertencia para disuadir a los usuarios de usar formularios no seguros. Para obtener más información sobre las implementaciones de Firefox al respecto, consulta el artículo Contraseñas inseguras.

+ +

Contenido oculto

+ +

Otro control de texto original es el tipo de entrada hidden. Se usa para crear un control de formulario que es invisible para el usuario, pero que aun así se envía al servidor junto con el resto de los datos del formulario una vez se transmiten; por ejemplo, es posible que desees enviar una marca de tiempo al servidor que indique cuándo se realizó un pedido. Al estar oculto, el usuario no puede ver ni editar su valor intencionadamente, el control nunca recibirá el foco y un lector de pantalla tampoco lo detectará.

+ +
<input type="hidden" id="timestamp" name="timestamp" value="1286705410">
+
+ +

Si creas un elemento así, es necesario establecer sus atributos name y value. Su valor puede establecerse dinámicamente a través de JavaScript. El tipo de entrada oculta no debe tener ninguna etiqueta asociada.

+ +

Otros tipos de entrada de texto, como {{HTMLElement ("input / search", "search")}}, {{HTMLElement ("input / url", "url")}} y {{HTMLElement ("input / tel" , "tel")}}, se añadieron con HTML5. Se tratarán en el próximo artículo: Tipos de entrada HTML5.

+ +

Elementos de selección: casillas de verificación y botones de opción

+ +

Los elementos de selección (o checkable items, en inglés) son controles cuyo estado puede cambiar cuando se hace clic en ellos o en sus etiquetas asociadas. Hay dos tipos de elementos de selección: las casillas de verificación (o check boxes) y los botones de opción (o radio buttons). Ambos usan el atributo checked para indicar si el control de formulario está seleccionado por defecto o no.

+ +

Vale la pena señalar que estos controles no se comportan exactamente como otros controles de formulario. Para la mayoría de los controles de formulario, cuando se envía el formulario, se envían todos los controles que tienen un atributo name, incluso si en ellos no se ha introducido ningún valor. En el caso de elementos de selección, sus valores se envían solo si están seleccionados. Si no están seleccionados, no se envía nada, ni siquiera su nombre. Si están seleccionados pero no tienen ningún valor asignado, el nombre se envía con el valor on.

+ +
+

Nota: Puedes encontrar los ejemplos de esta sección en GitHub como checkable-items.html (o consultarlos en vivo).

+
+ +

Para una usabilidad/accesibilidad óptima, te recomendamos delimitar cada lista de elementos que estén relacionados entre sí dentro de un elemento {{htmlelement ("fieldset")}} con un elemento {{htmlelement ("legend")}} que proporcione una descripción general de la lista. Cada par individual de elementos {{htmlelement ("label")}}/{{htmlelement ("input")}} ha de estar contenido en un elemento de lista propio (o similar). El elemento {{htmlelement ('label')}} asociado se coloca en general inmediatamente después del botón de opción o la casilla de verificación, con las instrucciones para el grupo de botones de opción o casillas de verificación, que suelen ser el contenido del elemento {{htmlelement ("legend")}}. Observa las estructuras de ejemplo en los ejemplos asociados anteriores.

+ +

Casillas de verificación

+ +

Las casillas de verificación se crean estableciendo el atributo type del elemento {{HTMLElement ("input")}} en el valor {{HTMLElement ("input / checkbox", "checkbox")}}.

+ +
<input type="checkbox" id="carrots" name="carrots" value="carrots" checked>
+
+ +

Al incluir el atributo checked, la casilla de verificación se marca automáticamente cuando se carga la página. Al hacer clic en la casilla de verificación o en su etiqueta asociada, la casilla de verificación se activa o desactiva.

+ +

Las capturas de pantalla siguientes muestran casillas de verificación predeterminadas, activas (con el foco) y deshabilitadas en Firefox 71 y Safari 13 en macOS y Chrome 79 y Edge 18 en Windows 10:

+ +

Casillas de verificación predeterminadas, activas y deshabilitadas en Firefox 71 y Safari 13 en Mac y Chrome 79 y Edge 18 en Windows 10

+ +
+

Nota: Las casillas de verificación y los botones de opción con atributo checked al cargarse coinciden con la pseudoclase {{cssxref (':default')}}, incluso aunque ya no estén seleccionadas. Las que están seleccionadas coinciden con la pseudoclase {{cssxref(':checked')}}.

+
+ +

Debido a su naturaleza activa-inactiva, las casillas de verificación se consideran botones de conmutación, y muchos desarrolladores y diseñadores han ampliado el estilo de casilla de verificación predeterminado para crear botones que parecen interruptores de conmutación. Aquí puedes ver un ejemplo en acción (observa también el código fuente).

+ +

Botón de opción

+ +

Un botón de opción se crea estableciendo el atributo {{htmlattrxref ("type", "input")}} del elemento {{HTMLElement ("input")}} en el valor radio:

+ +
<input type="radio" id="soup" name="meal" checked>
+ +

Es posible asociar diversos botones de opción. Si comparten el mismo valor de atributo {{htmlattrxref ("name", "input")}}, se considera que están en el mismo grupo de botones. Solo un botón dentro de un grupo puede estar activado en cada momento. Esto significa que cuando uno de ellos se selecciona, todos los demás se deseleccionan automáticamente. Al enviar el formulario, solo se envía el valor del botón de opción seleccionado. Si ninguno de ellos está seleccionado, se considera que el conjunto completo de botones de opción está en un estado desconocido y no se envía ningún valor con el formulario. Cuando en un grupo de botones con el mismo nombre se selecciona uno de los botones de opción, no es posible deseleccionar todos los botones sin reiniciar el formulario.

+ +
<fieldset>
+  <legend>¿Cuál es tu comida favorita?</legend>
+  <ul>
+    <li>
+      <label for="soup">Sopa</label>
+      <input type="radio" id="soup" name="meal" value="soup" checked>
+    </li>
+    <li>
+      <label for="curry">Curry</label>
+      <input type="radio" id="curry" name="meal" value="curry">
+    </li>
+    <li>
+      <label for="pizza">Pizza</label>
+      <input type="radio" id="pizza" name="meal" value="pizza">
+    </li>
+  </ul>
+</fieldset>
+ +

Las capturas de pantalla siguientes muestran botones de opción sin seleccionar y seleccionados, algunos con el foco y otros desactivados sin seleccionar y seleccionados, en Firefox 71 y Safari 13 en MacOS y Chrome 79 y Edge 18 en Windows 10.

+ +

Botones de opción en Firefox 71 y Safari 13 en Mac y Chrome 79 y Edge 18 en Windows 10

+ +

Botones

+ +

El botón de opción no es realmente un botón, a pesar de su nombre; sigamos adelante y echemos un vistazo a los controles de formulario que son botones propiamente. Hay tres tipos de entrada según el tipo de botones que se utilicen:

+ +
+
submit
+
Envía los datos del formulario al servidor. Para los elementos {{HTMLElement ("button")}}, omitir el atributo type (o introducir un valor de tipo no válido) da como resultado un botón de envío (submit).
+
reset
+
Restablece todos los controles de formulario a sus valores por defecto.
+
button
+
Botones que no tienen efecto automático, pero que se pueden personalizar con código JavaScript.
+
+ +

Además, el elemento {{htmlelement ("button")}} puede tomar un atributo type para imitar estos tres tipos de entrada. La diferencia principal entre los dos es que los elementos <button> propiamente admiten aplicación de estilo en mayor medida.

+ +
+

Nota: El tipo de entrada image también se representa como un botón. También desarrollaremos este tema más adelante.

+
+ +
+

Nota: Puedes encontrar los ejemplos de esta sección en GitHub como button-examples.html (o consultarlos en vivo).

+
+ +

A continuación puedes encontrar ejemplos de cada tipo de botón <input>, junto con el tipo de botón equivalente.

+ +

enviar

+ +
<button type="submit">
+    Este es un <strong>botón de envío</strong>
+</button>
+
+<input type="submit" value="Este es un botón de envío">
+ +

reiniciar

+ +
<button type="reset">
+    Este es un <strong>botón de reinicio</strong>
+</button>
+
+<input type="reset" value="Este es un botón de reinicio">
+ +

anónimo

+ +
<button type="button">
+    Este es un <strong>botón anónimo</strong>
+</button>
+
+<input type="button" value="Este es un botón anónimo">
+ +

Los botones siempre se comportan igual, independientemente de su usas un elemento {{HTMLElement ("button")}} o un elemento {{HTMLElement ("input")}}. Sin embargo, como puedes ver en los ejemplos, los elementos {{HTMLElement ("button")}} te permiten usar HTML en tu contenido, que se inserta entre las etiquetas <button> de apertura y cierre. Los elementos {{HTMLElement ("input")}}, por otro lado, son elementos vacíos; el contenido que muestran está inserto en el atributo value y, por lo tanto, solo acepta contenido de texto sin formato.

+ +

Los ejemplos siguientes muestran los tipos de entrada de botones predeterminados, activos y deshabilitados: en Firefox 71 y Safari 13 en macOS, y Chrome 79 y Edge 18 en Windows 10.

+ +

Tipos de entrada de botones predeterminados, activos y deshabilitados en Firefox 71 y Safari 13 en Mac y Chrome 79 y Edge 18 en Windows 10

+ +

Botón de imagen

+ +

El control botón de imagen se muestra exactamente como un elemento {{HTMLElement ("img")}}, excepto que cuando el usuario hace clic en él, se comporta como un botón de envío.

+ +

Se crea un botón de imagen usando un elemento {{HTMLElement ("input")}} con su atributo {{htmlattrxref ("type","input")}} establecido en el valor image. Este elemento admite exactamente el mismo conjunto de atributos que el elemento {{HTMLElement ("img")}}, además de todos los atributos que admiten el resto de botones de formulario.

+ +
<input type="image" alt="¡Púlsame!" src="my-img.png" width="80" height="30">
+ +

Si el botón de imagen se usa para enviar un formulario, este control no envía su valor; en lugar de ello se envían las coordenadas X e Y del clic que se ha hecho sobre la imagen (las coordenadas son relativas a la imagen, lo que significa que la esquina superior izquierda de la imagen representa la coordenada (0, 0)). Las coordenadas se envían como dos pares clave/valor:

+ + + +

Por ejemplo, cuando haces clic en las coordenadas (123, 456) de la imagen y se hace el envío por el método get, verás los valores añadidos a la URL de la manera siguiente:

+ +
http://foo.com?pos.x=123&pos.y=456
+ +

Esta es una forma muy cómoda de construir un «mapa dinámico». La forma en que se envían y recuperan estos valores se detalla en el artículo Enviar los datos del formulario.

+ +

Selector de archivos

+ +

Hay un último tipo de <input> que nos llegó a principios del HTML: el tipo entrada de archivo. Los formularios pueden enviar archivos a un servidor (esta acción específica también se detalla en el artículo Enviar los datos del formulario). El control de selección de archivos se puede usar para elegir uno o más archivos para enviar.

+ +

Para crear un control de selección de archivos, utilizas el elemento {{HTMLElement ("input")}} con su atributo {{htmlattrxref ("type","input")}} establecido en file. Es posible restringir los tipos de archivos que se aceptan utilizando el atributo {{htmlattrxref ("accept","input")}}. Además, puedes permitir que el usuario elija más de un archivo añadiendo el atributo {{htmlattrxref ("multiple","input")}}.

+ +

Ejemplo

+ +

En este ejemplo, se crea un control de selección de archivos que solicita archivos de imágenes gráficas. El usuario puede seleccionar múltiples archivos en este caso.

+ +
<input type="file" name="file" id="file" accept="image/*" multiple>
+ +

En algunos dispositivos móviles, el control de selección de archivos puede acceder a fotos, vídeos y audio capturados directamente por la cámara y el micrófono del dispositivo y añadir información de captura al atributo accept de la manera siguiente:

+ +
<input type="file" accept="image/*;capture=camera">
+<input type="file" accept="video/*;capture=camcorder">
+<input type="file" accept="audio/*;capture=microphone">
+ +

Atributos comunes

+ +

Muchos de los elementos que se utilizan para definir controles de formulario tienen sus atributos específicos propios. Sin embargo, hay un conjunto de atributos que son comunes para todos los elementos de formulario. Ya has conocido algunos, pero a continuación encontrarás una lista de esos atributos comunes para referencias futuras:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre del atributoValor por defectoDescripción
autofocusfalseEste atributo booleano te permite especificar que el elemento ha de tener el foco de entrada automáticamente cuando se carga la página. En un documento, solo un elemento asociado a un formulario puede tener este atributo especificado.
disabledfalseEste atributo booleano indica que el usuario no puede interactuar con el elemento. Si no se especifica este atributo, el elemento hereda su configuración del elemento que lo contiene, por ejemplo, {{HTMLElement ("fieldset")}}. Si el elemento que lo contiene no tiene el atributo establecido en disabled, el elemento está habilitado.
formEl elemento <form> con el que está asociado el control, que se usa cuando no está anidado dentro de ese formulario. El valor del atributo debe ser el atributo id de un elemento {{HTMLElement ("form")}} del mismo documento. Esto te permite asociar un formulario con un control de formulario que esté fuera de aquel, incluso si está dentro de un elemento de formulario diferente.
nameEl nombre del elemento; se envía con los datos del formulario.
valueEl valor inicial del elemento.
+ +

Conclusión

+ +

Este artículo ha expuesto los tipos de entrada más antiguos: el conjunto original que se introdujo en los primeros días de HTML, que es compatible con todos los navegadores. En el artículo siguiente veremos los valores del atributo type que se han añadido en HTML5 más recientemente.

+ +

{{PreviousMenuNext("Learn/Forms/How_to_structure_an_HTML_form", "Learn/Forms/HTML5_input_types", "Learn/Forms")}}

+ +

En este módulo

+ + + +

Temas avanzados

+ + diff --git a/files/es/learn/html/forms/tipos_input_html5/index.html b/files/es/learn/html/forms/tipos_input_html5/index.html new file mode 100644 index 0000000000..d463399e93 --- /dev/null +++ b/files/es/learn/html/forms/tipos_input_html5/index.html @@ -0,0 +1,276 @@ +--- +title: Tipos de input de HTML5 +slug: Learn/HTML/Forms/Tipos_input_HTML5 +translation_of: Learn/Forms/HTML5_input_types +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Forms/Basic_native_form_controls", "Learn/Forms/Other_form_controls", "Learn/Forms")}}
+ +

En el artículo anterior vimos el elemento {{htmlelement("input")}} y los valores de su atributo type, disponibles desde los inicios de HTML. Ahora veremos en detalle la funcionalidad de los controles de formulario más recientes, incluyendo algunos tipos de input nuevos, los cuales fueron añadidos en HTML5 para permitir la recolección de tipos de datos específicos

+ + + + + + + + + + + + +
Requisitos previos:Formación básica en informática, y una comprensión básica de HTML.
Objetivo:Entender los valores de tipo input disponibles más recientes para crear controles de formulario nativos, y cómo implementarlos utilizando HTML.
+ +
+

Nota: La mayoría de las características discutidas en este artículo tienen un amplio soporte en todos los navegadores, anotaremos cualquier excepción. Si quieres más detalles referente al soporte de navegadores, deberías consultar nuestra referéncia de elementos de formulario HTML, y en particular nuestra referéncia extensiva de Tipos de <input>.

+
+ +

Debido a que la apariéncia de un control de formulario puede ser algo distinta con respecto a unas especificaciones del diseñador, los desarrolladores web a veces construyen sus propios controles de formulario personalizados. Cubrimos este aspecto en un tutorial avanzado: Cómo construir widgets de formulario personalizados.

+ +

Campo de dirección de correo electrónico

+ +

Este tipo de campo se define utilizando el valor  email en el atributo {{htmlattrxref("type","input")}} del elemento <input>:

+ +
<input type="email" id="email" name="email">
+ +

Cuando se utiliza este valor {{htmlattrxref("type","input")}} , se le obliga al usuario a escribir dentro del campo una dirección de correo electrónico válida. Cualquier otro contenido ocasiona que el navegador muestre un mensaje de error cuando se envía el formulario. Puedes verlo en acción en la siguiente captura de pantalla

+ +

An invalid email input showing the message "Please enter an email address."

+ +

Puedes utilizar también el atributo multiple en combinación con el tipo inputemail para permitir que sean introducidas varias direcciones de correo electrónico separadas por comas en el mismo input:

+ +
<input type="email" id="email" name="email" multiple>
+ +

En algunos dispositivos, en particular dispositivos táctiles con teclados dinámicos como los smart phones, debería presentarse un teclado virtual que es más adecuado para introducir direcciones de correo electrónico, incluyendo la tecla @. Mira como ejemplo la siguiente captura de pantalla del teclado de Firefox para Android:

+ +

firefox for android email keyboard, with ampersand displayed by default.

+ +
+

Nota: Puedes encontrar ejemplos sobre los tipos de entrada de texto básicos en Ejemplos input básicos (Consulta también el código fuente).

+
+ +

Mejorar la experiéncia del usuario para usuarios con estos dispositivos, es otra buena razón para utilizar estos tipos de input más recientes.

+ +

Validación del lado cliente

+ +

Como puedes haber visto anteriormente, email, junto con otros tipos de input más recientes, proporciona la validación de errores en el lado cliente de forma predeterminada, realizados por el navegador antes de que los datos obtenidos se envíen al servidor. Es una ayuda útil guiar a los usuarios a rellenar un formulario de forma precisa y puede ahorrar tiempo: es útil saber de inmediato que tu dato no es correcto, en vez de tener que esperar el viaje de ida y vuelta al servidor.

+ +

Pero no debería ser considerado una medida de seguridad exhaustiva! Tus aplicaciones siempre deben realizar comprobaciones de seguridad en cada dato, tanto en el lado servidor como en el lado cliente debido a que la validación en el lado cliente es muy fácil desactivarla, por lo que usuarios malintencionados pueden enviar fácilmente datos incorrectos al servidor. Lee Seguridad en el sitio web para tener una idea de lo que podría ocurrir; Implementar validación en el lado servidor está más allá del alcance de este módulo-guía, pero debería tenerlo en cuenta.

+ +

Ten en cuenta que a@b es una dirección de correo electrónico válida de acuerdo a las restricciones proporcionadaas por defecto. Esto es debido a que el tipo de input email, permite por defecto direcciones de correo electrónico de una intranet. Para implementar un comportamiento diferente de validación puedes utilizar el atributo pattern, y también puedes utilizar mensajes de error personalizados; Hablaremos de cómo utilizar estas características en Validación de formularios en el lado cliente en un artículo posterior.

+ +
+

Nota: Si los datos introducidos no son una dirección de correo electrónico, habrá coincidéncia con la pseudo clase {{cssxref(':invalid')}}, y la propiedad {{domxref('validityState.typeMismatch')}} devolverá true.

+
+ +

Campo de búsqueda

+ +

Los campos de búsqueda están destinados a ser utilizados para crear cajas de búsqueda en páginas y aplicaciones. Este tipo de campo se define utilizando el valor search en su atributo {{htmlattrxref("type","input")}}:

+ +
<input type="search" id="search" name="search">
+ +

La diferéncia principal entre un campo text y un campo search, es la forma en que el navegador aplica estilo a su apariéncia. A menudo los campos search se muestran con bordes redondeados; y a veces también muestran una "Ⓧ", el cual despeja el campo de cualquier valor cuando se pulsa sobre él. Adicionalmente, en dispositivos con teclado dinámico, la tecla enter del teclado puede leer "search" o mostrar un icono de lupa.

+ +

La captura de pantalla siguiente muestra un campo de búsqueda con contenido, en Firefox 71, Safari 13, y Chrome 79 en macOS, y Edge 18 y Chrome 79 en Windows 10. Ten en cuenta que el icono de reseteo sólo aparece si el campo tiene un valor y, aparte de Safari, sólo se muestra cuando el campo tiene el foco.

+ +

Screenshots of search fields on several platforms.

+ +

Otra característica que vale la pena señalar es que se puede guardar los valores de un campo search automáticamente y reutilizarse en múltiples páginas del mismo sitio web para ofrecer autocompletado. Esta característica suele ocurrir de forma automática en la mayoría de navegadores modernos.

+ +

Campo número de teléfono

+ +

Se puede crear un campo especial para introducir números de teléfono utilizando tel como valor del atributo {{htmlattrxref("type","input")}}:

+ +
<input type="tel" id="tel" name="tel">
+ +

Cuando se accede desde un dispositivo táctil con teclados dinámicos, muchos de ellos mostrarán un teclado numérico cuando se encuentren con type="tel", lo que significa que este tipo es útil no sólo para ser utilizado para números de teléfono, sino también cuando sea útil un teclado numérico.

+ +

La siguiente captura de pantalla del teclado de Firefox para Android proporciona un ejemplo:

+ +

firefox for android email keyboard, with ampersand displayed by default.

+ +

Debido a la gran variedad de formatos de número de teléfono existentes, este tipo de campo no cumple con ningún tipo de restricción sobre el valor introducido por el usuario. (Esto significa que puede incluir letras, etc...).

+ +

Como mencionamos anteriormente, se puede utilizar el atributo pattern para que asuma restricciones, sobre el cuál aprenderemos en Validación de formulario en el lado cliente.

+ +

Campo URL

+ +

Se puede crear un tipo especial de campo para introducir URLs utilizando el valor url para el atributo {{htmlattrxref("type","input")}}:

+ +
<input type="url" id="url" name="url">
+ +

Este tipo añade restricciones de validación en el campo. El navegador informará de un error si no se introdujo el protocolo (como http:), o si de algún modo el URL está mal formado. En dispositivos con teclados dinámicos a menudo mostrará por defecto algunas o todas las teclas como los dos puntos, el punto, y la barra inclinada.

+ +

Mira el siguiente ejemplo tomado de Firefox para Android:

+ +

firefox for android email keyboard, with ampersand displayed by default.

+ +
Nota: Solo porque el URL esté bien formado no significa necesariamente que la dirección al que hace referéncia exista!
+ +

Campo numérico

+ +

Se pueden crear controles para introducir números con el {{htmlattrxref("type","input")}} number de {{HTMLElement("input")}}. Este control se parece a un campo de texto pero solo permite números de punto flotante, y normalmente proporciona botones deslizadores para incrementar o reducir el valor del control. En dispositivos con teclados dinámicos generalmente se muestra el teclado numérico.

+ +

La siguiente captura de pantalla tomada de Firefox para Android proporciona un ejemplo:

+ +

firefox for android email keyboard, with ampersand displayed by default.

+ +

Con el tipo de input number  puedes limitar los valores mínimo y máximo permitidos definiendo los atributos {{htmlattrxref("min","input")}} y  {{htmlattrxref("max","input")}}.

+ +

También puedes utilizar el atributo step para cambiar el incremento y decremento causado por los botones deslizadores. Por defecto, el tipo de input number sólo valida si el número es un entero. Para permitir números decimales, especifica step="any". Si se omite, su valor por defecto es 1, lo que significa que solo son válidos números enteros.

+ +

Miremos algunos ejemplos. El primero de los siguientes crea un control numérico cuyo valor está restringido a cualquier valor entre 1 y 10, y sus botones cambian su valor en incrementos o decrementos de 2.

+ +
<input type="number" name="age" id="age" min="1" max="10" step="2">
+ +

El segundo crea un control numérico cuyo valor está restringido a cualquier valor entre el 0 y 1 ambos inclusive, y sus botones cambian su valor en incrementos o decrementos de 0.01.

+ +
<input type="number" name="change" id="pennies" min="0" max="1" step="0.01">
+ +

El tipo de input number tiene sentido cuando esté limitado el rango de valores válidos, por ejemplo la edad de una persona o su altura. Si el rango es demasiado grande para que los cambios de incremento tengan sentido ( por ejemplo los códigos postales de USA, cuyo rango va de 00001 a 99999), entonces sería una mejor opción utilizar el tipo tel: proporciona el teclado numérico mientras que omite el componente de interfaz de usuario de los deslizadores de número.

+ +
+

Ten en cuenta que: En versiones inferiores a la 10 de Internet Explorer no se soportan las entradas number

+
+ +

Slider controls

+ +

Otra forma de tomar un número es usando un slider. Podrás observar cómo son bastantes parecidas a los sitios inmobiliarios, dónde quieres determinar un máximo de precio por propiedad y filtrar tu búsqueda en el. Observaremos un ejemplo en vivo.

+ +

{{EmbedGHLiveSample("learning-area/html/forms/range-example/index.html", '100%', 200)}}

+ +

Usage-wise, sliders are less accurate than text fields. Therefore, they are used to pick a number whose precise value is not necessarily important.

+ +

A slider is created using the {{HTMLElement("input")}} with its {{htmlattrxref("type","input")}} attribute set to the value range. The slider-thumb can be moved via mouse or touch, or with the arrows of the keypad.

+ +

It's important to properly configure your slider. To that end, it's highly recommended that you set the min, max, and step attributes which set the minimum, maximum and increment values, respectively.

+ +

Let's look at the code behind the above example, so you can see how its done. First of all, the basic HTML:

+ +
<label for="price">Choose a maximum house price: </label>
+<input type="range" name="price" id="price" min="50000" max="500000" step="100" value="250000">
+<output class="price-output" for="price"></output>
+ +

This example creates a slider whose value may range between 50000 and 500000, which increments/decrements by 100 at a time. We've given it default value of 250000, using the value attribute.

+ +

One problem with sliders is that they don't offer any kind of visual feedback as to what the current value is. This is why we've included an {{htmlelement("output")}} element — to contain the current value (we'll also look at this element in the next article). You could display an input value or the output of a calculation inside any element, but <output> is special — like <label>, it can take a for attribute that allows you to associate it with the element or elements that the output value came from.

+ +

To actually display the current value, and update it as it changed, you must use JavaScript, but this is relatively easy to do:

+ +
const price = document.querySelector('#price')
+const output = document.querySelector('.price-output')
+
+output.textContent = price.value
+
+price.addEventListener('input', function() {
+  output.textContent = price.value
+});
+ +

Here we store references to the range input and the output in two variables. Then we immediately set the output's textContent to the current value of the input. Finally, an event listener is set to ensure that whenever the range slider is moved, the output's textContent is updated to the new value.

+ +
+

Note: range inputs are not supported in versions of Internet Explorer below 10.

+
+ +

Date and time pickers

+ +

Gathering date and time values has traditionally been a nightmare for web developers. For good user experience, it is important to provide a calendar selection UI, enabling users to select dates without necessating context switching to a native calendar application or potentially entering them in differing formats that are hard to parse. The last minute of the previous millenium can be expressed in the following different ways, for example: 1999/12/31, 23:59 or 12/31/99T11:59PM.

+ +

HTML date controls are available to handle this specific kind of data, providing calendar widgets and making the data uniform.

+ +

A date and time control is created using the {{HTMLElement("input")}} element and an appropriate value for the {{htmlattrxref("type","input")}} attribute, depending on whether you wish to collect dates, times, or both. Here's a live example that falls back to {{htmlelement("select")}} elements in non-supporting browsers:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/datetime-local-picker-fallback/index.html", '100%', 200)}}

+ +

Let's look at the different available types in brief. Note that the usage of these types is quite complex, especially considering browser support (see below); to find out the full details, follow the links below to the reference pages for each type, including detailed examples.

+ +

datetime-local

+ +

<input type="datetime-local"> creates a widget to display and pick a date with time with no specific time zone information.

+ +
<input type="datetime-local" name="datetime" id="datetime">
+ +

month

+ +

<input type="month"> creates a widget to display and pick a month with a year.

+ +
<input type="month" name="month" id="month">
+ +

time

+ +

<input type="time"> creates a widget to display and pick a time value. While time may display in 12-hour format, the value returned is in 24-hour format.

+ +
<input type="time" name="time" id="time">
+ +

week

+ +

<input type="week"> creates a widget to display and pick a week number and its year.

+ +

Weeks start on Monday and run to Sunday. Additionally, the first week 1 of each year contains the first Thursday of that year—which may not include the first day of the year, or may include the last few days of the previous year.

+ +
<input type="week" name="week" id="week">
+ +

Constraining date/time values

+ +

All date and time controls can be constrained using the min and max attributes, with further constraining possible via the step attribute (whose value varies according to input type).

+ +
<label for="myDate">When are you available this summer?</label>
+<input type="date" name="myDate" min="2013-06-01" max="2013-08-31" step="7" id="myDate">
+ +

Browser support for date/time inputs

+ +

You should be warned that the date and time widgets don't have the best browser support. At the moment, Chrome, Edge, and Opera support them well, but there is no support in Internet Explorer, Safari has some mobile support (but no desktop support), and Firefox supports time and date only.

+ +

The reference pages linked to above provide suggestions on how to program fallbacks for non-supporting browsers; another option is to consider using a JavaScript library to provide a date picker. Most modern frameworks have good components available to provide this functionality, and there are standalone libraries available to (see Top date picker javascript plugins and libraries for some suggestions).

+ +

Color picker control

+ +

Colors are always a bit difficult to handle. There are many ways to express them: RGB values (decimal or hexadecimal), HSL values, keywords, etc.

+ +

A color control can be created using the {{HTMLElement("input")}} element with its {{htmlattrxref("type","input")}} attribute set to the value color:

+ +
<input type="color" name="color" id="color">
+ +

When supported, clicking a color control will tend to display the operating system's default color picking functionality for you to actually make your choice with. The following screenshot taken on Firefox for macOS provides an example:

+ +

firefox for android email keyboard, with ampersand displayed by default.

+ +

And here is a live example for you to try out:

+ +

{{EmbedGHLiveSample("learning-area/html/forms/color-example/index.html", '100%', 200)}}

+ +

The value returned is always a lowercase 6-value hexidecimal color.

+ +
+

Note: color inputs are not supported in Internet Explorer.

+
+ +

Summary

+ +

That brings us to the end of our tour of the HTML5 form input types. There are a few other control types that cannot be easily grouped together due to their very specific behaviors, but which are still essential to know about. We cover those in the next article.

+ +

{{PreviousMenuNext("Learn/Forms/Basic_native_form_controls", "Learn/Forms/Other_form_controls", "Learn/Forms")}}

+ +

In this module

+ + + +

Advanced Topics

+ + diff --git a/files/es/learn/html/forms/validacion_formulario_datos/index.html b/files/es/learn/html/forms/validacion_formulario_datos/index.html new file mode 100644 index 0000000000..e967b68973 --- /dev/null +++ b/files/es/learn/html/forms/validacion_formulario_datos/index.html @@ -0,0 +1,845 @@ +--- +title: Validación de formularios de datos +slug: Learn/HTML/Forms/Validacion_formulario_datos +tags: + - Ejemplo + - Guía + - HTML + - Intermedio + - JavaScript + - Web + - formulários +translation_of: Learn/Forms/Form_validation +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}
+ +

Antes de enviar datos al servidor, es importante asegurarse de que se completan todos los controles de formulario requeridos, y en el formato correcto. Esto se denomina validación de formulario en el lado del cliente y ayuda a garantizar que los datos que se envían coinciden con los requisitos establecidos en los diversos controles de formulario. Este artículo te guiará por los conceptos básicos y ejemplos de validación de formularios en el lado del cliente.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, y entender cómo funcionan el HTML, el CSS y el JavaScript.
Objetivo:Entender qué es la validación de formularios en el lado del cliente, porqué es importante y cómo aplicar diversas técnicas para implementarla.
+ +

La validación en el lado del cliente es una verificación inicial y una característica importante para garantizar una buena experiencia de usuario; mediante la detección de datos no válidos en el lado del cliente, el usuario puede corregirlos de inmediato. Si el servidor lo recibe y, a continuación, lo rechaza; se produce un retraso considerable en la comunicación entre el servidor y el cliente que insta al usuario a corregir sus datos.

+ +

Sin embargo, ¡la validación en el lado del cliente no debe considerarse una medida de seguridad exhaustiva! Tus aplicaciones siempre deben realizar comprobaciones de seguridad de los datos enviados por el formulario en el lado del servidor, así como también en el lado del cliente, porque la validación en el lado del cliente es demasiado fácil de evitar, por lo que los usuarios malintencionados pueden enviar fácilmente datos incorrectos a tu servidor. Lee Seguridad en los sitios web para ver qué podría suceder. Cómo implementar la validación en el lado del servidor está fuera del alcance de este módulo, pero debes tenerlo en cuenta.

+ +

¿Qué es la validación de formularios?

+ +

Ve a cualquier sitio web popular que incluya un formulario de registro y observa que proporcionan comentarios cuando no introduces tus datos en el formato que se espera. Recibirás mensajes como:

+ + + +

Esto se llama validación de formulario. Cuando introduces los datos, el navegador y/o el servidor web verifican que estén en el formato correcto y dentro de las restricciones establecidas por la aplicación. La validación realizada en el navegador se denomina validación en el lado del cliente, mientras que la validación realizada en el servidor se denomina validación en el lado del servidor. En este capítulo nos centraremos en la validación en el lado del cliente.

+ +

Si la información está en el formato correcto, la aplicación permite que los datos se envíen al servidor y (en general) que se guarden en una base de datos; si la información no está en el formato correcto, da al usuario un mensaje de error que explica lo que debe corregir y le permite volver a intentarlo.

+ +

Queremos que completar formularios web sea lo más fácil posible. Entonces, ¿por qué insistimos en validar nuestros formularios? Hay tres razones principales:

+ + + +
Atención: No confíes nunca en los datos que se pasan al servidor desde el cliente. Incluso si tu formulario se valida correctamente y evita la introducción de datos con formato incorrecto en el lado del cliente, un usuario malintencionado puede alterar la petición de red.
+ +

Diferentes tipos de validación en el lado del cliente

+ +

Hay dos tipos diferentes de validación por parte del cliente que encontrarás en la web:

+ + + +

Usar la validación de formulario incorporada

+ +

Una de las características más importantes de los controles de formulario de HTML5 es la capacidad de validar la mayoría de los datos de usuario sin depender de JavaScript. Esto se realiza mediante el uso de atributos de validación en los elementos del formulario. Los hemos visto anteriormente en el curso, pero recapitulamos aquí:

+ + + +

Si los datos que se introducen en un campo de formulario siguen todas las reglas que especifican los atributos anteriores, se consideran válidos. Si no, se consideran no válidos.

+ +

Cuando un elemento es válido, se cumplen los aspectos siguientes:

+ + + +

Cuando un elemento no es válido, se cumplen los aspectos siguientes:

+ + + +
+

Nota: Hay varios errores que evitan que el formulario se envíe, incluidos {{domxref('validityState.badInput', 'badInput')}}, {{domxref('validityState.patternMismatch','patternMismatch')}}, {{domxref('validityState.rangeOverflow','rangeOverflow')}} o {{domxref('validityState.rangeUnderflow','rangeUnderflow')}}, {{domxref('validityState.stepMismatch','stepMismatch')}}, {{domxref('validityState.tooLong','tooLong')}} o {{domxref('validityState.tooShort','tooShort')}}, {{domxref('validityState.typeMismatch','typeMismatch')}}, {{domxref('validityState.valueMissing','valueMissing')}} o {{domxref('validityState.customError','customError')}}.

+
+ +

Ejemplos de validación de formularios incorporados

+ +

En esta sección probaremos algunos de los atributos que hemos comentado antes.

+ +

Archivo de inicio sencillo

+ +

Vamos a empezar con un ejemplo sencillo: una entrada que te permite elegir si prefieres un plátano o una cereza. Este ejemplo implica una simple entrada ({{HTMLElement("input")}}) de texto con una etiqueta ({{htmlelement("label")}}) asociada y un botón de envío ({{htmlelement ("button")}}). Puedes encontrar el código fuente en GitHub en fruit-start.html y el ejemplo en vivo a continuación.

+ +
<form>
+  <label for="choose">¿Prefieres un plátano o una cereza?</label>
+  <input id="choose" name="i_like">
+  <button>Enviar</button>
+</form>
+ +
input:invalid {
+  border: 2px dashed red;
+}
+
+input:valid {
+  border: 2px solid black;
+}
+ +

{{EmbedLiveSample("Archivo_de_inicio_sencillo", "100%", 80)}}

+ +

Para empezar, haz una copia de fruit-start.html en un nuevo directorio de tu disco duro.

+ +

El atributo required

+ +

La característica de validación de HTML5 más simple es el atributo required. Añade este atributo al elemento para que una entrada sea obligatoria. Cuando se establece este atributo, el elemento coincide con la pseudoclase de la interfaz de usuario {{cssxref(':required')}} y el formulario no se envía; muestra un mensaje de error al enviarlo si la entrada está vacía. Si está vacía, la entrada también se considera inválida, coincidiendo con la pseudoclase de interfaz de usuario {{cssxref(':invalid')}}.

+ +

Añade un atributo required a tu entrada, como se muestra a continuación.

+ +
<form>
+  <label for="choose">¿Prefieres un plátano o una cereza? (requerido) </label>
+  <input id="choose" name="i_like" required>
+  <button>Enviar</button>
+</form>
+ +

Ten en cuenta el CSS que en el archivo de ejemplo se ha incluido:

+ +
input:invalid {
+  border: 2px dashed red;
+}
+
+input:invalid:required {
+  background-image: linear-gradient(to right, pink, lightgreen);
+}
+
+input:valid {
+  border: 2px solid black;
+}
+ +

Este CSS da un borde discontinuo rojo cuando la entrada no es válida, y un borde negro sólido más sutil cuando es válida. También añadimos un gradiente de fondo cuando la entrada es obligatoria y no válida. Prueba el nuevo comportamiento en el ejemplo siguiente:

+ +

{{EmbedLiveSample("El_atributo_required", "100%", 80)}}

+ +
+

Nota: Puedes encontrar este ejemplo en vivo en GitHub como fruit-validation.html (consulta también el código fuente).

+
+ +

Intenta enviar el formulario sin introducir ningún valor. Observa que la entrada no válida recibe el cursor, aparece un mensaje de error predeterminado («Complete este campo») y el formulario no se puede enviar.

+ +

La presencia del atributo required en cualquier elemento que admite este atributo significa que el elemento coincide con la pseudoclase {{cssxref(':required')}}, tenga o no un valor. Si en el elemento {{HTMLElement("input")}} no se ha introducido ningún valor, input coincidirá con la pseudoclase {{cssxref(':invalid')}}.

+ +
+

Nota: Para una buena experiencia de usuario, indica al usuario que campos de formulario se requieren. No solo es una buena experiencia de usuario, sino que lo exigen las pautas de accesibilidad de WCAG. Además, solo requiere que los usuarios introduzcan los datos que realmente necesitas: Por ejemplo, ¿por qué realmente necesitas saber el género o el tratamiento de alguien?

+
+ +

Validación de una expresión regular

+ +

Otra característica útil de validación es el atributo pattern, que espera una expresión regular como valor. Una expresión regular (regex) es un patrón que se puede usar para establecer combinaciones de caracteres en cadenas de texto, por lo que las expresiones regulares son ideales para la validación de formularios y sirven para una gran variedad de otros usos en JavaScript.

+ +

Las expresiones regulares son bastante complejas y no vamos a exponerlas exhaustivamente en este artículo. A continuación hay algunos ejemplos para que te hagas una idea de cómo funcionan.

+ + + +

Hay muchas más posibilidades que no exponemos aquí. Para obtener una lista completa y muchos ejemplos, consulta nuestro documento de expresiones regulares.

+ +

Implementemos un ejemplo. Actualiza tu HTML para añadir un atributo pattern como este:

+ +
<form>
+  <label for="choose">¿Prefieres un plátano o una cereza?</label>
+  <input id="choose" name="i_like" required pattern="[Pp]látano|[Cc]ereza ">
+  <button>Enviar</button>
+</form>
+
+ + + +

Esto nos da la siguiente actualización; pruébalo:

+ +

{{EmbedLiveSample("Validación de una expresión regular", "100%", 80)}}

+ +
+

Nota: Puedes encontrar este ejemplo en vivo en GitHub como fruit-pattern.html (consulta también su código fuente).

+
+ +

En este ejemplo, el elemento {{HTMLElement("input")}} acepta uno de los cuatro valores posibles: las cadenas «plátano», «Plátano», «cereza» o «Cereza». Las expresiones regulares distinguen entre mayúsculas y minúsculas, pero hemos hecho que admita versiones en mayúsculas y minúsculas utilizando un patrón «Aa» adicional anidado dentro de corchetes.

+ +

En este punto, intenta cambiar el valor dentro del atributo pattern para que se vean iguales que algunos de los ejemplos vistos anteriormente, y observa que esto afecta a los valores que puedes añadir para que el valor de entrada sea válido. Intenta escribir algo por tu cuenta y mira cómo va. ¡Haz que estén relacionadas con la fruta siempre que sea posible para que tus ejemplos tengan sentido!

+ +

Si un valor no vacío de {{HTMLElement("input")}} no coincide con el patrón de la expresión regular, input coincidirá con la pseudoclase {{cssxref(':invalid')}}.

+ +
+

Nota: Algunos tipos de elementos {{HTMLElement ("input")}} no necesitan validar una expresión regular con el atributo pattern. Especificar el tipo de correo electrónico (email), por ejemplo, valida el valor de las entradas con un patrón de dirección de correo electrónico bien formado o un patrón que coincida con una lista de direcciones de correo electrónico separadas por comas si tiene el atributo multiple.

+
+ +
+

Nota: El elemento {{HTMLElement("textarea")}} no admite el atributo pattern.

+
+ +

Restringir la longitud de tus entradas

+ +

Puedes restringir la longitud de los caracteres de todos los campos de texto creados por {{HTMLElement("input")}} o {{HTMLElement("textarea")}} utilizando los atributos minlength y maxlength. Un campo no es válido si tiene un valor y ese valor tiene menos caracteres que el valor de longitud mínima (minlength), o más que el valor de longitud máxima (maxlength).

+ +

Los navegadores a menudo no permiten que el usuario escriba un valor más largo de lo esperado en los campos de texto. Lo que otorga una mejor experiencia de usuario que maxlength es proporcionar comentarios de recuento de caracteres de manera accesible y permitirles editar su contenido a un tamaño más reducido. Un ejemplo de esto es el límite de caracteres de Twitter. JavaScript, incluidas las soluciones que utilizan maxlength, se puede utilizar para proporcionar esta funcionalidad.

+ +

Restringir los valores de tus entradas

+ +

Los atributos min y max se pueden usar para proporcionar a los campos numéricos (es decir, <input type="number">) un rango de valores válidos. El campo no será válido si contiene un valor fuera de este rango.

+ +

Veamos otro ejemplo. Crea una nueva copia del archivo fruit-start.html.

+ +

Ahora elimina el contenido del elemento <body> y reemplázalo con lo siguiente:

+ +
<form>
+  <div>
+    <label for="choose">¿Prefieres un plátano o una cereza?</label>
+    <input type="text" id="choose" name="i_like" required minlength="6" maxlength="6">
+  </div>
+  <div>
+    <label for="number">¿Cuántos te gustaría comer?</label>
+    <input type="number" id="number" name="amount" value="1" min="1" max="10">
+  </div>
+  <div>
+    <button>Enviar</button>
+  </div>
+</form>
+ + + + + +

Aquí está el ejemplo que se ejecuta en vivo:

+ +

{{EmbedLiveSample("Restringir_los_valores_de_tus_entradas", "100%", 100)}}

+ +
+

Nota: Puedes encontrar este ejemplo en vivo en GitHub como fruit-length.html (consulta también su código fuente).

+
+ +
+

Nota: <input type="number"> (y otros tipos, como range y date) también pueden tomar un atributo step, que especifica en qué incremento aumenta o disminuye el valor cuando se utilizan los controles de entrada (como el botones numéricos arriba y abajo). En el ejemplo anterior no hemos incluido un atributo step, por lo que el valor predeterminado es 1. Esto significa que los valores de coma flotante, como 3.2, también se mostrarán como no válidos.

+
+ +

Ejemplo completo

+ +

Aquí hay un ejemplo completo que muestra el uso de las funciones de validación integradas en HTML. En primer lugar, un poco de HTML:

+ +
<form>
+  <p>
+    <fieldset>
+      <legend>¿Tienes carné de conducir?<abbr title="Este campo es obligatorio" aria-label="required">*</abbr></legend>
+      <!-- Solo se puede seleccionar un botón de opción en un grupo con el mismo nombre,
+           y, por lo tanto, solo un botón de opción en un grupo con el mismo nombre que tiene marcado el atributo «requerido»
+           basta para hacer de una selección un requisito -->
+      <input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Sí</label>
+      <input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
+    </fieldset>
+  </p>
+  <p>
+    <label for="n1">¿Qué edad tienes?</label>
+    <!-- El atributo pattern puede actuar como una alternativa para los navegadores que
+         no implementan el tipo de entrada de número, pero admiten el atributo pattern.
+         Ten en cuenta que los navegadores que admiten el atributo pattern lo harán
+         fallar silenciosamente cuando se use con un campo numérico.
+         Su uso aquí solo actúa como una alternativa -->
+     <input type="number" min="12" max="120" step="1" id="n1" name="age"
+           pattern="\d+">
+  </p>
+  <p>
+    <label for="t1">¿Cuál es tu fruta favorita?<abbr title="Este campo es obligatorio" aria-label="required">*</abbr></label>
+    <input type="text" id="t1" name="fruit" list="l1" required
+           pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range ">
+    <datalist id="l1">
+      <option>Plátano</option>
+      <option>Cereza</option>
+      <option>Manzana</option>
+      <option>Fresa</option>
+      <option>Limón</option>
+      <option>Naranja</option>
+     </datalist>
+  </p>
+  <p>
+    <label for="t2">¿Cuál es tu dirección de correo electrónico? </label>
+    <input type="email" id="t2" name="email">
+  </p>
+  <p>
+    <label for="t3">Deja un mensaje</label>
+    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
+  </p>
+  <p>
+    <button>Enviar</button>
+  </p>
+</form>
+ +

Y ahora, algo de CSS para añadir estilo al HTML:

+ +
form {
+  font: 1em sans-serif;
+  max-width: 320px;
+}
+
+p > label {
+  display: block;
+}
+
+input[type="text"],
+input[type="email"],
+input[type="number"],
+textarea,
+fieldset {
+  width : 100%;
+  border: 1px solid #333;
+  box-sizing: border-box;
+}
+
+input:invalid {
+  box-shadow: 0 0 5px 1px red;
+}
+
+input:focus:invalid {
+  box-shadow: none;
+}
+ +

Esto se traduce de la siguiente manera:

+ +

{{EmbedLiveSample("Ejemplo_completo", "100%", 420)}}

+ +

Consulta Atributos relacionados con la validación para obtener una lista completa de los atributos que se pueden usar para restringir los valores de entrada y los tipos de entrada que los admiten.

+ +
+

Nota: Puedes encontrar este ejemplo en vivo en GitHub como full-example.html (consulta también su código fuente).

+
+ +

Validar formularios utilizando JavaScript

+ +

Debes usar JavaScript si quieres controlar la apariencia de los mensajes de error nativos o tratar con navegadores heredados que no admiten la validación de formularios incorporados en HTML. En esta sección veremos las diferentes formas de hacer esto.

+ +

La API de validación de restricciones

+ +

La mayoría de los navegadores admiten la API de validación de restricciones, que consta de un conjunto de métodos y propiedades disponibles en las interfaces DOM de elementos de formulario siguientes:

+ + + +

La API de validación de restricciones hace que las propiedades siguientes estén disponibles en los elementos anteriores.

+ + + +

La API de validación de restricciones también pone a disposición los siguientes métodos en los elementos anteriores.

+ + + +

Implementar un mensaje de error personalizado

+ +

Como has visto en los ejemplos de restricciones de validación de HTML5 anteriores, cada vez que un usuario intenta enviar un formulario no válido, el navegador muestra un mensaje de error. La forma en que se muestra este mensaje depende del navegador.

+ +

Estos mensajes automatizados tienen dos inconvenientes:

+ + + +

Ejemplo de un mensaje de error en francés en una página de Firefox en inglés

+ +

La personalización de estos mensajes de error es uno de los casos de uso más comunes de la API de validación de restricciones. Veamos un ejemplo simple de cómo hacer esto.

+ +

Comenzaremos con un HTML simple (siéntete libre de poner esto en un archivo HTML en blanco; usa una copia nueva de fruit-start.html como base, si lo deseas):

+ +
<form>
+  <label for="mail">Me gustaría que me proporcionara una dirección de correo electrónico:<label>
+  <input type="email" id="mail" name="mail">
+  <button>Enviar</button>
+</form>
+ +

Y añade a la página el JavaScript siguiente:

+ +
const email = document.getElementById("mail");
+
+email.addEventListener("input", function (event) {
+  if (email.validity.typeMismatch) {
+    email.setCustomValidity("¡Se esperaba una dirección de correo electrónico!");
+  } else {
+    email.setCustomValidity("");
+  }
+});
+ +

Aquí guardamos una referencia para la entrada de la dirección de correo electrónico, luego le añadimos un detector de eventos que ejecuta el código de content cada vez que el valor de la entrada cambia.

+ +

Dentro del código que contiene, verificamos si la propiedad validity.typeMismatch de la entrada de la dirección de correo electrónico devuelve true, lo que significa que el valor que contiene no coincide con el patrón para una dirección de correo electrónico bien formada. Si es así, llamamos al método setCustomValidity() con un mensaje personalizado. Esto hace que la entrada no sea válida, de modo que cuando intentas enviar el formulario, el envío falla y se muestra el mensaje de error personalizado.

+ +

Si la propiedad validity.typeMismatch devuelve false, llamamos al método setCustomValidity() con una cadena vacía. Esto hace que la entrada sea válida, y el formulario se envía.

+ +

Puedes probarlo a continuación:

+ +

{{EmbedGHLiveSample("/en-US/learning-area/html/forms/form-validation/custom-error-message.html", '100%', 80)}}

+ +
+

Nota: Puede encontrar este ejemplo vivo en GitHub como custom-error-message.html (véase también su código fuente).

+
+ +

Un ejemplo más detallado

+ +

Ahora que hemos visto un ejemplo realmente sencillo, veamos cómo podemos usar esta API para construir una validación personalizada un poco más compleja.

+ +

En primer lugar, el código HTML. Una vez más, siéntete libre de construir esto junto con nosotros:

+ +
<form novalidate>
+  <p>
+    <label for="mail">
+      <span>Por favor, introduzca una dirección de correo electrónico: </span>
+      <input type="email" id="mail" name="mail" required minlength="8">
+      <span class="error" aria-live="polite"></span>
+    </label>
+  </p>
+  <button>Enviar</button>
+</form>
+ +

Este sencillo formulario usa el atributo novalidate para desactivar la validación automática del navegador; esto permite que nuestra secuencia de comandos tome control sobre la validación. Sin embargo, esto no deshabilita la compatibilidad para la API de validación de restricciones ni la aplicación de pseudoclases de CSS como {{cssxref(":valid")}}, etc. Eso significa que, aunque el navegador no verifica automáticamente la validez del formulario antes de enviar los datos, puedes hacerlo tú mismo y diseñar el formulario en consecuencia.

+ +

Nuestra entrada para validar es <input type="email">, que es obligatoria y tiene una longitud mínima (minlength) de 8 caracteres. Vamos a verificar esto con nuestro propio código para que muestre un mensaje de error personalizado para cada elemento.

+ +

Nuestro objetivo es mostrar los mensajes de error dentro de un elemento <span>. El atributo aria-live se establece en ese <span> para asegurar que todo el mundo podrá ver nuestro mensaje de error personalizado, incluidos los usuarios de lectores de pantalla.

+ +
+

Nota: Un punto clave a tener en cuenta es que establecer el atributo novalidate en el formulario impide que el formulario muestre sus propios cuadros de diálogo de error, y nos permite mostrar los mensajes de error personalizados en el DOM de la manera que nosotros elijamos.

+
+ +

Ahora aplicaremos algo de CSS básico para mejorar ligeramente el aspecto del formulario y proporcionar algunos comentarios visuales cuando los datos de entrada no sean válidos:

+ +
body {
+  font: 1em sans-serif;
+  width: 200px;
+  padding: 0;
+  margin : 0 auto;
+}
+
+p * {
+  display: block;
+}
+
+input[type=email]{
+  -webkit-appearance: none;
+  appearance: none;
+
+  width: 100%;
+  border: 1px solid #333;
+  margin: 0;
+
+  font-family: inherit;
+  font-size: 90%;
+
+  box-sizing: border-box;
+}
+
+/* Este es nuestro diseño para los campos no válidos */
+input:invalid{
+  border-color: #900;
+  background-color: #FDD;
+}
+
+input:focus:invalid {
+  outline: none;
+}
+
+/* Este es el diseño para nuestros mensajes de error */
+.error {
+  width : 100%;
+  padding: 0;
+
+  font-size: 80%;
+  color: white;
+  background-color: #900;
+  border-radius: 0 0 5px 5px;
+
+  box-sizing: border-box;
+}
+
+.error.active {
+  padding: 0.3em;
+}
+ +

Vamos a ver el JavaScript que implementa la validación de error personalizada.

+ +
// Hay muchas formas de elegir un nodo DOM; aquí obtenemos el formulario y, a continuación, el campo de entrada
+// del correo electrónico, así como el elemento span en el que colocaremos el mensaje de error.
+const form  = document.getElementsByTagName('form')[0];
+
+const email = document.getElementById('mail');
+const emailError = document.querySelector('#mail + span.error');
+
+email.addEventListener('input', function (event) {
+  // Cada vez que el usuario escribe algo, verificamos si
+  // los campos del formulario son válidos.
+
+  if (email.validity.valid) {
+    // En caso de que haya un mensaje de error visible, si el campo
+    // es válido, eliminamos el mensaje de error.
+    emailError.innerHTML = ''; // Restablece el contenido del mensaje
+    emailError.className = 'error'; // Restablece el estado visual del mensaje
+  } else {
+    // Si todavía hay un error, muestra el error exacto
+    showError();
+  }
+});
+
+form.addEventListener('submit', function (event) {
+  // si el campo de correo electrónico es válido, dejamos que el formulario se envíe
+
+  if(!email.validity.valid) {
+    // Si no es así, mostramos un mensaje de error apropiado
+    showError();
+    // Luego evitamos que se envíe el formulario cancelando el evento
+    event.preventDefault();
+  }
+});
+
+function showError() {
+  if(email.validity.valueMissing) {
+    // Si el campo está vacío
+    // muestra el mensaje de error siguiente.
+    emailError.textContent = 'Debe introducir una dirección de correo electrónico.';
+  } else if(email.validity.typeMismatch) {
+    // Si el campo no contiene una dirección de correo electrónico
+    // muestra el mensaje de error siguiente.
+    emailError.textContent = 'El valor introducido debe ser una dirección de correo electrónico.';
+  } else if(email.validity.tooShort) {
+    // Si los datos son demasiado cortos
+    // muestra el mensaje de error siguiente.
+    emailError.textContent = 'El correo electrónico debe tener al menos ${ email.minLength } caracteres; ha introducido ${ email.value.length }.';
+  }
+
+  // Establece el estilo apropiado
+  emailError.className = 'error activo';
+}
+ +

Los comentarios explican las cosas bastante bien, pero de una manera muy breve:

+ + + +

Este es el resultado:

+ +

{{EmbedGHLiveSample("/en-US/learning-area/html/forms/form-validation/detailed-custom-validation.html", '100%', 150)}}

+ +
+

Nota: Puedes encontrar este ejemplo en vivo en GitHub como detailed-custom-validation.html (consulta también su código fuente).

+
+ +

La API de validación de restricciones te proporciona una herramienta poderosa para manejar la validación de formularios, y te permite tener un control enorme sobre la interfaz de usuario más allá de lo que puedas hacer solo con HTML y CSS.

+ +
+

Nota: Para obtener más información, consulta nuestra guía de validación de restricciones y la referencia de API de validación de restricciones.

+
+ +

Validar formularios sin una API incorporada

+ +

En algunos casos, como la compatibilidad heredada del navegador o los controles personalizados, no podrás o no querrás usar la API de validación de restricciones. Todavía puedes usar JavaScript para validar tu formulario, pero vas a tener que escribirlo.

+ +

Antes de validar el formulario, hazte estas preguntas:

+ +
+
¿Qué tipo de validación debería realizar?
+
Debes determinar cómo validar los datos: operaciones de cadena, conversión de tipos, expresiones regulares, etc. Tú decides.
+
¿Qué debo hacer si el formulario no se valida?
+
Esto es claramente un problema de la interfaz de usuario. Tienes que decidir cómo se comportará el formulario. ¿El formulario va a enviar los datos de todos modos? ¿Deberías resaltar los campos que dan error? ¿Deberías mostrar mensajes de error?
+
¿Cómo puedo ayudar al usuario a corregir datos no válidos?
+
Para reducir la frustración del usuario, es muy importante proporcionar tanta información útil como sea posible para guiarlo a fin de que corrija sus entradas de datos. Debes ofrecer sugerencias por adelantado para que sepan lo que se espera de ellos, así como mensajes de error claros. Si deseas profundizar en los requisitos de interfaz de usuario para la validación de formularios, aquí hay algunos artículos útiles que debes leer: + +
+
+ +

Un ejemplo que no usa la API de validación de restricciones

+ +

Para ilustrar esto, mostramos una versión simplificada del ejemplo anterior que funciona con navegadores con compatibilidad heredada.

+ +

El HTML es casi el mismo; solo hemos eliminado las funciones de validación de HTML.

+ +
<form>
+  <p>
+    <label for="mail">
+        <span>Por favor, introduzca una dirección de correo electrónico: </span>
+        <input type="text" class="mail" id="mail" name="mail">
+        <span class="error" aria-live="polite"></span>
+    </label>
+  </p>
+  <!-- Algunos navegadores con compatibilidad heredada deben tener el atributo «type»
+       establecido explícitamente en el elemento «button» de «submit»-->
+  <button type="submit">Enviar</button>
+</form>
+ +

Del mismo modo, no es necesario cambiar mucho el CSS; acabamos de convertir la pseudoclase {{cssxref(":invalid")}} de CSS en una clase real y evitamos usar el selector de atributos que no funciona en Internet Explorer 6.

+ +
body {
+  font: 1em sans-serif;
+  width: 200px;
+  padding: 0;
+  margin : 0 auto;
+}
+
+form {
+  max-width: 200px;
+}
+
+p * {
+  display: block;
+}
+
+input.mail {
+  -webkit-appearance: none;
+
+  width: 100%;
+  border: 1px solid #333;
+  margin: 0;
+
+  font-family: inherit;
+  font-size: 90%;
+
+  box-sizing: border-box;
+}
+
+/* Este es nuestro diseño para los campos no válidos */
+input.invalid{
+  border-color: #900;
+  background-color: #FDD;
+}
+
+input:focus.invalid {
+  outline: none;
+}
+
+/* Este es el diseño para nuestros mensajes de error */
+.error {
+  width : 100%;
+  padding: 0;
+
+  font-size: 80%;
+  color: white;
+  background-color: #900;
+  border-radius: 0 0 5px 5px;
+  box-sizing: border-box;
+}
+
+.error.active {
+  padding: 0.3em;
+}
+ +

Los grandes cambios están en el código JavaScript, que necesita hacer mucho más trabajo pesado.

+ +
// Hay menos formas de elegir un nodo DOM con navegadores antiguos
+const form  = document.getElementsByTagName('form')[0];
+const email = document.getElementById('mail');
+
+// Lo siguiente es un truco para llegar al siguiente nodo de elementos hermanos en el DOM
+// Esto es peligroso porque puedes construir fácilmente un bucle infinito.
+// En los navegadores modernos es mejor usar element.nextElementSibling
+let error = email;
+while ((error = error.nextSibling).nodeType != 1);
+
+// según la especificación HTML5
+const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
+
+// Muchos navegadores antiguos no son compatibles con el método addEventListener.
+// Aquí hay una manera simple de manejar esto; está lejos de ser la única.
+function addEvent(element, event, callback) {
+  let previousEventCallBack = element["on"+event];
+  element["on"+event] = function (e) {
+    const output = callback(e);
+
+    // Una devolución de llamada que devuelve «false» detiene la cadena de devolución de llamada
+    // e interrumpe la ejecución de la devolución de llamada del evento.
+    if (output === false) return false;
+
+    if (typeof previousEventCallBack === 'function') {
+      output = previousEventCallBack(e);
+      if(output === false) return false;
+    }
+  }
+};
+
+// Ahora podemos reconstruir nuestra restricción de validación
+// Debido a que no confiamos en la pseudoclase de CSS, tenemos que
+// establecer explícitamente la clase valid/invalid en nuestro campo de correo electrónico
+addEvent(window, "load", function () {
+  // Aquí probamos si el campo está vacío (recuerda, el campo no es obligatorio)
+  // Si no es así, verificamos si su contenido es una dirección de correo electrónico con el formato correcto.
+  const test = email.value.length === 0 || emailRegExp.test(email.value);
+
+  email.className = test ? "valid" : "invalid";
+});
+
+// Esto define lo que sucede cuando el usuario escribe en el campo
+addEvent(email, "input", function () {
+  const test = email.value.length === 0 || emailRegExp.test(email.value);
+  if (test) {
+    email.className = "valid";
+    error.innerHTML = "";
+    error.className = "error";
+  } else {
+    email.className = "invalid";
+  }
+});
+
+// Esto define lo que sucede cuando el usuario intenta enviar los datos.
+addEvent(form, "submit", function () {
+  const test = email.value.length === 0 || emailRegExp.test(email.value);
+
+  if (!test) {
+    email.className = "invalid";
+    error.innerHTML = "I expect an e-mail, darling!";
+    error.className = "error active";
+
+    // Algunos navegadores antiguos no son compatibles con el método event.preventDefault ()
+    return false;
+  } else {
+    email.className = "valid";
+    error.innerHTML = "";
+    error.className = "error";
+  }
+});
+ +

El resultado es el siguiente:

+ +

{{EmbedLiveSample("Validar_formularios_sin_una_API_incorporada", "100%", 130)}}

+ +

Como puedes ver, no es tan difícil construir un sistema de validación por tu cuenta. La parte difícil es hacer que sea lo suficientemente genérico para que se pueda usar en diferentes plataformas y en cualquier forma. Hay muchas bibliotecas de archivos disponibles para realizar la validación de formularios, como por ejemplo Validate.js

+ +

.

+ +

Prueba tus habilidades!

+ +

Has llegado al final de este artículo pero ¿puedes recordar la información más importante?Puedes encontrar pruebas adicionales para comprovar que has comprendido la información antes de que continue — visita Prueba tus habilidades: Validación de formularios.

+ +

Resumen

+ +

La validación de formularios en el lado del cliente a veces requiere JavaScript si deseas personalizar el estilo y los mensajes de error, pero siempre requiere que pienses cuidadosamente en el usuario. Recuerda que siempre debes ayudar a tus usuarios a corregir los datos que proporcionan. Para ese fin, asegúrate de:

+ + + +

Una vez que hayas verificado que el formulario se ha completado correctamente, puedes proceder a enviarlo. Vamos a exponer el envío de los datos del formulario en el próximo artículo.

+ +

{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}

+ +

En este módulo

+ + + +

Temas avanzados

+ + diff --git a/files/es/learn/html/forms/your_first_html_form/index.html b/files/es/learn/html/forms/your_first_html_form/index.html new file mode 100644 index 0000000000..df9d73bc60 --- /dev/null +++ b/files/es/learn/html/forms/your_first_html_form/index.html @@ -0,0 +1,305 @@ +--- +title: Mi primer formulario HTML +slug: Learn/HTML/Forms/Your_first_HTML_form +tags: + - Ejemplo + - Guía + - HTML + - Principiante + - Web + - formulários +translation_of: Learn/Forms/Your_first_form +--- +
{{LearnSidebar}}{{NextMenu("Learn/Forms/How_to_structure_a_web_form", "Learn/Forms")}}
+ +

El primer artículo de nuestra serie te proporciona una primera experiencia de creación de un formulario web, que incluye diseñar un formulario sencillo con controles de formulario adecuados y otros elementos HTML, añadir un poco de estilo muy simple con CSS y describir cómo se envían los datos a un servidor. Ampliaremos cada uno de estos subtemas más adelante.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática y de lenguaje HTML.
Objetivo:Familiarizarse con los formularios web, para qué se usan, cómo diseñarlos y qué elementos HTML básicos vas a necesitar para casos sencillos.
+ +

¿Qué son los formularios web?

+ +

Los formularios web son uno de los principales puntos de interacción entre un usuario y un sitio web o aplicación. Los formularios permiten a los usuarios la introducción de datos, que generalmente se envían a un servidor web para su procesamiento y almacenamiento (consulta Enviar los datos de un formulario más adelante en el módulo), o se usan en el lado del cliente para provocar de alguna manera una actualización inmediata de la interfaz (por ejemplo, se añade otro elemento a una lista, o se muestra u oculta una función de interfaz de usuario).

+ +

El HTML de un formulario web está compuesto por uno o más controles de formulario (a veces llamados widgets), además de algunos elementos adicionales que ayudan a estructurar el formulario general; a menudo se los conoce como formularios HTML. Los controles pueden ser campos de texto de una o varias líneas, cajas desplegables, botones, casillas de verificación o botones de opción, y se crean principalmente con el elemento {{htmlelement("input")}}, aunque hay algunos otros elementos que también hay que conocer.

+ +

Los controles de formulario también se pueden programar para forzar la introducción de formatos o valores específicos (validación de formulario), y se combinan con etiquetas de texto que describen su propósito para los usuarios con y sin discapacidad visual.

+ +

Diseñar tu formulario

+ +

Antes de comenzar a escribir código, siempre es mejor dar un paso atrás y tomarte el tiempo necesario para pensar en tu formulario. Diseñar una maqueta rápida te ayudará a definir el conjunto de datos adecuado que deseas pedirle al usuario que introduzca. Desde el punto de vista de la experiencia del usuario (UX), es importante recordar que cuanto más grande es tu formulario, más te arriesgas a frustrar a las personas y perder usuarios. Tiene que ser simple y conciso: solicita solo los datos que necesitas.

+ +

Diseñar formularios es un paso importante cuando creas un sitio web o una aplicación. Va más allá del alcance de este artículo exponer la experiencia de usuario de los formularios, pero si deseas profundizar en ese tema, puedes leer los artículos siguientes:

+ + + +

En este artículo, vamos a crear un formulario de contacto sencillo. Hagamos un esbozo.

+ +

Esbozo aproximado del formulario que vamos a construir

+ +

Nuestro formulario va a tener tres campos de texto y un botón. Le pedimos al usuario su nombre, su correo electrónico y el mensaje que desea enviar. Al pulsar el botón sus datos se enviarán a un servidor web.

+ +

Aprendizaje activo: La implementación de nuestro formulario HTML

+ +

De acuerdo, intentemos crear el HTML para nuestro formulario. Vamos a utilizar los elementos HTML siguientes: {{HTMLelement("form")}}, {{HTMLelement("label")}}, {{HTMLelement("input")}}, {{HTMLelement("textarea")}} y {{HTMLelement("button")}}.

+ +

Antes de continuar, haz una copia local de nuestra plantilla HTML simple: introduce aquí tu formulario HTML.

+ +

El elemento {{HTMLelement("form")}}

+ +

Todos los formularios comienzan con un elemento {{HTMLelement("form")}}, como este:

+ +
<form action="/my-handling-form-page" method="post">
+
+</form>
+ +

Este elemento define formalmente un formulario. Es un elemento contenedor, como un elemento {{HTMLelement("section")}} o {{HTMLelement("footer")}}, pero específico para contener formularios; también admite algunos atributos específicos para la configuración de la forma en que se comporta el formulario. Todos sus atributos son opcionales, pero es una práctica estándar establecer siempre al menos los atributos action y method:

+ + + +
+

Nota: Veremos cómo funcionan esos atributos en nuestro artículo Enviar los datos de un formulario que encontrarás más adelante.

+
+ +

Por ahora, añade el elemento {{htmlelement("form")}} anterior a tu elemento HTML {{htmlelement("body")}}.

+ +

Los elementos {{HTMLelement("label")}}, {{HTMLelement("input")}} y {{HTMLelement("textarea")}}

+ +

Nuestro formulario de contacto no es complejo: la parte para la entrada de datos contiene tres campos de texto, cada uno con su elemento {{HTMLelement("label")}} correspondiente:

+ + + +

En términos de código HTML, para implementar estos controles de formulario necesitamos algo como lo siguiente:

+ +
<form action="/my-handling-form-page" method="post">
+ <ul>
+  <li>
+    <label for="name">Nombre:</label>
+    <input type="text" id="name" name="user_name">
+  </li>
+  <li>
+    <label for="mail">Correo electrónico:</label>
+    <input type="email" id="mail" name="user_mail">
+  </li>
+  <li>
+    <label for="msg">Mensaje:</label>
+    <textarea id="msg" name="user_message"></textarea>
+  </li>
+ </ul>
+</form>
+ +

Actualiza el código de tu formulario para que se vea como el anterior.

+ +

Los elementos {{HTMLelement("li")}} están ahí para estructurar nuestro código convenientemente y facilitar la aplicación de estilo (ver más adelante en el artículo). Por motivos de usabilidad y accesibilidad incluimos una etiqueta explícita para cada control de formulario. Ten en cuenta el uso del atributo for en todos los elementos {{HTMLelement("label")}}, que toma como valor el id del control de formulario con el que está asociado; así es como asocias un formulario con su etiqueta.

+ +

Hacer esto presenta muchas ventajas porque la etiqueta está asociada al control del formulario y permite que los usuarios con ratón, panel táctil y dispositivos táctiles hagan clic en la etiqueta para activar el control correspondiente, y también proporciona accesibilidad con un nombre que los lectores de pantalla leen a sus usuarios. Encontrarás más detalles sobre las etiquetas de los formularios en Cómo estructurar un formulario web.

+ +

En el elemento {{HTMLelement("input")}}, el atributo más importante es type. Este atributo es muy importante porque define la forma en que el elemento {{HTMLelement("input")}} aparece y se comporta. Encontrarás más información sobre esto en el artículo sobre Controles de formularios nativos básicos más adelante.

+ + + +

Por último, pero no por ello menos importante, ten en cuenta la sintaxis de <input> en contraposición con la de <textarea></textarea>. Esta es una de las rarezas del HTML. La etiqueta <input> es un elemento vacío, lo que significa que no necesita una etiqueta de cierre. El elemento {{HTMLElement("textarea")}} no es un elemento vacío, lo que significa que debe cerrarse con la etiqueta de cierre adecuada. Esto tiene un impacto en una característica específica de los formularios: el modo en que defines el valor predeterminado. Para definir el valor predeterminado de un elemento {{HTMLElement("input")}}, debes usar el atributo value de esta manera:

+ +
<input type="text" value="por defecto este elemento se llena con este texto">
+ +

Por otro lado, si deseas definir un valor predeterminado para un elemento {{HTMLElement("textarea")}}, lo colocas entre las etiquetas de apertura y cierre del elemento {{HTMLElement("textarea")}}, así:

+ +
<textarea>
+Por defecto, este elemento contiene este texto
+</textarea>
+ +

El elemento {{HTMLelement("button")}}

+ +

El marcado de nuestro formulario está casi completo; solo necesitamos añadir un botón para permitir que el usuario envíe sus datos una vez que haya completado el formulario. Esto se hace con el elemento {{HTMLelement("button")}}; añade lo siguiente justo encima de la etiqueta de cierre </form>:

+ +
<li class="button">
+  <button type="submit">Envíe su mensaje</button>
+</li>
+ +

El elemento {{htmlelement("button")}} también acepta un atributo de type, que a su vez acepta uno de estos tres valores: submit, reset o button.

+ + + +
+

Nota: También puedes usar el elemento {{HTMLElement("input")}} con el atributo type correspondiente para generar un botón, por ejemplo <input type="submit">. La ventaja principal del elemento {{HTMLelement("button")}} es que el elemento {{HTMLelement("input")}} solo permite texto sin formato en su etiqueta, mientras que el elemento {{HTMLelement("button")}} permite contenido HTML completo, lo que permite generar botones creativos más complejos.

+
+ +

Aplicar estilo básico a un formulario

+ +

Ahora que has terminado de escribir el código HTML de tu formulario, guárdalo y observa lo que ocurre en un navegador. Por ahora, se verá bastante feo.

+ +
+

Nota: Si crees que no has escrito bien el código HTML, compáralo con nuestro ejemplo final: véase first-form.html (ver en vivo).

+
+ +

Resulta notablemente difícil aplicar estilo a los formularios. Está más allá del alcance de este artículo enseñarte cómo aplicar estilo a los formularios en detalle, por lo que por el momento solo vamos a exponer cómo añadir un poco de CSS para que se vea un poco bien.

+ +

En primer lugar, añade un elemento {{htmlelement("style")}} a tu página, dentro de la cabecera del HTML. Debe quedar así:

+ +
<style>
+
+</style>
+ +

Dentro de las etiquetas style, añade el código CSS siguiente:

+ +
form {
+  /* Centrar el formulario en la página */
+  margin: 0 auto;
+  width: 400px;
+  /* Esquema del formulario */
+  padding: 1em;
+  border: 1px solid #CCC;
+  border-radius: 1em;
+}
+
+ul {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+form li + li {
+  margin-top: 1em;
+}
+
+label {
+  /* Tamaño y alineación uniforme */
+  display: inline-block;
+  width: 90px;
+  text-align: right;
+}
+
+input,
+textarea {
+  /* Para asegurarse de que todos los campos de texto tienen la misma configuración de letra
+     Por defecto, las áreas de texto tienen un tipo de letra monoespaciada */
+  font: 1em sans-serif;
+
+  /* Tamaño uniforme del campo de texto */
+  width: 300px;
+  box-sizing: border-box;
+
+  /* Hacer coincidir los bordes del campo del formulario */
+  border: 1px solid #999;
+}
+
+input:focus,
+textarea:focus {
+  /* Destacado adicional para elementos que tienen el cursor */
+  border-color: #000;
+}
+
+textarea {
+  /* Alinear los campos de texto multilínea con sus etiquetas */
+  vertical-align: top;
+
+  /* Proporcionar espacio para escribir texto */
+  height: 5em;
+}
+
+.button {
+  /* Alinear los botones con los campos de texto */
+  padding-left: 90px; /* mismo tamaño que los elementos de la etiqueta */
+}
+
+button {
+  /* Este margen adicional representa aproximadamente el mismo espacio que el espacio
+     entre las etiquetas y sus campos de texto */
+  margin-left: .5em;
+}
+ +

Guarda y vuelve a cargar, y observa que tu formulario presenta un aspecto mucho menos feo.

+ +
+

Nota: Puedes encontrar nuestra versión en GitHub en first-form-styled.html (ver en vivo).

+
+ +

Enviar los datos del formulario a un servidor web

+ +

La última parte, y quizás la más complicada, es manejar los datos del formulario en el lado del servidor. El elemento {{HTMLelement("form")}} define dónde y cómo enviar los datos gracias a los atributos action y method.

+ +

Proporcionamos un nombre (name) a cada control de formulario. Los nombres son importantes tanto en el lado del cliente como del servidor; le dicen al navegador qué nombre debe dar a cada dato y, en el lado del servidor, dejan que el servidor maneje cada dato por su nombre. Los datos del formulario se envían al servidor como pares de nombre/valor.

+ +

Para poner nombre a los diversos datos que se introducen en un formulario, debes usar el atributo name en cada control de formulario que recopila un dato específico. Veamos de nuevo algunos de nuestros códigos de formulario:

+ +
<form action="/my-handling-form-page" method="post">
+ <ul>
+  <li>
+    <label for="name">Nombre:</label>
+    <input type="text" id="name" name="user_name" />
+  </li>
+  <li>
+    <label for="mail">Correo electrónico:</label>
+    <input type="email" id="mail" name="user_email" />
+  </li>
+  <li>
+    <label for="msg">Mensaje:</label>
+    <textarea id="msg" name="user_message"></textarea>
+  </li>
+
+  ...
+
+ +

En nuestro ejemplo, el formulario envía tres datos denominados «user_name», «user_email» y «user_message». Esos datos se envían a la URL «/my-handling-form-page» utilizando el método post de HTTP.

+ +

En el lado del servidor, la secuencia de comandos de la URL «/my-handling-form-page» recibe los datos como una lista de tres elementos clave/valor contenidos en la solicitud HTTP. La forma en que este script maneja esos datos depende de ti. Cada lenguaje de servidor (PHP, Python, Ruby, Java, C#, etc.) tiene su propio mecanismo de manipulación de datos de formulario. No profundizaremos sobre el tema en esta guía, pero si deseas obtener más información, proporcionamos algunos ejemplos en nuestro artículo Enviar los datos de un formulario que encontrarás más adelante.

+ +

Resumen

+ +

¡Enhorabuena!, has creado tu primer formulario web. Debería verse así:

+ +

{{ EmbedLiveSample('A_simple_form', '100%', '240', '', 'Learn/Forms/Your_first_form/Example') }}

+ +

Pero esto es solo el comienzo: ahora ha llegado el momento de profundizar en el tema. Los formularios tienen mucho más potencial de lo que hemos visto aquí y los artículos siguientes de este módulo te ayudarán a dominarlo.

+ +

{{NextMenu("Learn/Forms/How_to_structure_a_web_form", "Learn/Forms")}}

+ +

En este módulo

+ + + +

Temas avanzados

+ + diff --git a/files/es/learn/html/index.html b/files/es/learn/html/index.html new file mode 100644 index 0000000000..6262b7f957 --- /dev/null +++ b/files/es/learn/html/index.html @@ -0,0 +1,66 @@ +--- +title: HTML +slug: Learn/HTML +tags: + - Aprender + - Guía + - HTML + - Novato + - Principiante + - Tema + - introducción +translation_of: Learn/HTML +--- +
{{LearnSidebar}}
+ +

Para crear sitios web, debes conocer el {{Glossary('HTML')}} — la tecnología fundamental que se utiliza para definir la estructura de una página web. HTML se utiliza para especificar si tu contenido web se debe reconocer como un párrafo, lista, encabezado, enlace, imagen, reproductor multimedia, formulario o uno de los muchos otros elementos disponibles o incluso un nuevo elemento que tú definas.

+ +
+

¿Quieres transformarte en un desarrollador de la interfaz de usuario web?

+ +

Hemos elaborado un curso que incluye toda la información esencial que necesitas para trabajar hacia tu objetivo.

+ +

Empieza aquí

+
+ +

Prerrequisitos

+ + + +

Antes de comenzar con este tema, debes tener al menos una familiaridad básica con el uso de computadoras y el uso pasivo de la web (es decir, simplemente mirarlo, consumir el contenido). Debes tener un entorno de trabajo básico configurado como se detalla en {{web.link("/es/docs/Learn/Getting_started_with_the_web/Installing_basic_software", "Instalación de software básico")}}, y comprender cómo crear y administrar archivos, como se detalla en {{web.link("/es/docs/Learn/Getting_started_with_the_web/Dealing_with_files", "Manejo de archivos")}}; ambos son parte del módulo para principiantes en la {{web.link("/es/docs/Learn/Getting_started_with_the_web", "Introducción a la Web")}}.

+ +

Se recomienda que trabajes con {{web.link("/es/docs/Learn/Getting_started_with_the_web", "Comenzando con la web")}} antes de intentar este tema, sin embargo, no es absolutamente necesario; gran parte de lo que se cubre en el artículo {{web.link("/es/docs/Learn/Getting_started_with_the_web/HTML_basics", "conceptos básicos de HTML")}} también se cubre en el {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML", "Módulo de introducción a HTML")}}, aunque con mucho más detalle.

+ +

Después de comprender HTML, puedes pasar a aprender temas más avanzados como:

+ + + +

Módulos

+ +

Este tema contiene los siguientes módulos, en un orden sugerido para trabajar con ellos. Definitivamente deberías comenzar con el primero.

+ +
+
{{web.link("/es/docs/Learn/HTML/Introduction_to_HTML", "Introducción a HTML")}}
+
Este módulo prepara el escenario para que te acostumbres a conceptos y sintaxis importantes, explica cómo aplicar HTML al texto, cómo crear hipervínculos y cómo usar HTML para estructurar una página web.
+
{{web.link("/es/docs/Learn/HTML/Multimedia_and_embedding", "Multimedia e inserción")}}
+
Este módulo explora cómo usar HTML para incluir multimedia en tus páginas web, incluidas las diferentes formas en que se pueden incluir imágenes y cómo insertar video, audio e incluso otras páginas web completas.
+
{{web.link("/es/docs/Learn/HTML/Tables", "tablas HTML")}}
+
Representar datos tabulares en una página web de una manera comprensible y {{Glossary("Accessibility", "accesible")}} puede ser un desafío. Este módulo cubre el marcado básico de tablas, junto con características más complejas como la implementación de subtítulos y resúmenes.
+
+ +

Resolver problemas comunes de HTML

+ +

{{web.link("/es/docs/Learn/HTML/Howto", "Usa HTML para resolver problemas comunes")}} proporciona vínculos a secciones de contenido que explican cómo usar HTML para resolver muchos problemas comunes al crear una página web: lidiar con títulos, agregar imágenes o videos, enfatizar contenido, crear una forma básica, etc.

+ +

Ve también

+ +
+
{{web.link("/es/docs/Learn/HTML/Forms", "Formularios Web")}}
+
Este módulo proporciona una serie de artículos que te ayudarán a dominar los conceptos básicos de los formularios web. Los formularios web son una herramienta muy poderosa para interactuar con los usuarios — generalmente, se utilizan para recopilar datos de los usuarios o para permitirles controlar una interfaz de usuario. Sin embargo, por razones históricas y técnicas, no siempre es obvio cómo utilizarlos en todo su potencial. Aborda todos los aspectos esenciales de los formularios web, incluido el marcado de su estructura HTML, el diseño de controles de formulario, la validación de datos de formulario y el envío de datos al servidor.
+
{{web.link("/es/docs/Web/HTML", "HTML (lenguaje de marcado de hipertexto)")}}
+
El punto de entrada principal para la documentación de referencia HTML en MDN, incluidas las referencias detalladas de elementos y atributos; si deseas saber qué atributos tiene un elemento o qué valores tiene un atributo, por ejemplo, este es un excelente lugar para comenzar.
+
diff --git a/files/es/learn/html/introduccion_a_html/advanced_text_formatting/index.html b/files/es/learn/html/introduccion_a_html/advanced_text_formatting/index.html new file mode 100644 index 0000000000..7e96d3c6d7 --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/advanced_text_formatting/index.html @@ -0,0 +1,695 @@ +--- +title: Formateo de texto avanzado +slug: Learn/HTML/Introduccion_a_HTML/Advanced_text_formatting +tags: + - CodingScripting + - Guía + - HTML + - Lista de descripción + - Novato + - Principiante + - Texto + - abreviatura + - aprende + - cita + - semántica +translation_of: Learn/HTML/Introduction_to_HTML/Advanced_text_formatting +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}
+ +

Hay muchos otros elementos en HTML para dar formato al texto, que no expusimos en el artículo {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Fundamentos de texto HTML")}}. Los elementos descritos en este artículo son menos conocidos, pero aún así es muy útil conocerlos (no obstante, no es una lista completa de ninguna manera). Aquí aprenderás cómo marcar citas, listas de descripción, código de computadora y otro texto relacionado, subíndices y superíndices, información de contacto y mucho más.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con HTML, cubierto en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started", "Empezar con HTML")}}. Aplicación de formato a texto en documentos HTML, según lo expuesto en la sección {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Fundamentos de texto HTML")}}.
Objetivo:Aprender a utilizar elementos HTML menos conocidos para marcar características semánticas avanzadas.
+ +

Listas de descripciones

+ +

En los fundamentos del texto HTML, explicamos cómo {{web.link("/es/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals#Lists", "marcar listas básicas")}} en HTML, pero no mencionamos el tercer tipo de lista con la que te encontrarás ocasionalmente: listas de descripción. El propósito de estas listas es marcar un conjunto de elementos y sus descripciones asociadas, como términos y definiciones, o preguntas y respuestas. Veamos un ejemplo de un conjunto de términos y definiciones:

+ +
soliloquio
+En las obras dramáticas, corresponde a cuando un personaje se habla a sí mismo para representar sus pensamientos o sentimientos internos y, en el proceso, transmitirlos a la audiencia (pero no a otros personajes).
+monólogo
+En las obras dramáticas, corresponde a cuando un personaje habla de sus pensamientos en voz alta para compartirlos con el público y cualquier otro personaje presente.
+aparte
+En las obras dramáticas, corresponde a cuando un personaje comparte un comentario solo con la audiencia para dar efecto cómico o dramático. Suele ser un sentimiento, un pensamiento o información adicional.
+ +

Las listas de descripción utilizan un contenedor diferente al de los otros tipos de listas — {{HTMLElement("dl")}} («description list» o lista de descripciones); además, cada término está envuelto en un elemento {{HTMLElement("dt")}} («description term» o término a describir), y cada descripción está envuelta en un elemento {{HTMLElement("dd")}} («description definition» o definición de descripción). Para redondear esta información veamos un ejemplo:

+ +
+
<dl>
+  <dt>soliloquio</dt>
+  <dd>En las obras dramáticas, corresponde a cuando un personaje se habla a sí mismo para representar sus pensamientos o sentimientos internos y, en el proceso, transmitirlos a la audiencia (pero no a otros personajes).</dd>
+  <dt>monólogo</dt>
+  <dd>En las obras dramáticas, corresponde a cuando un personaje habla de sus pensamientos en voz alta para compartirlos con el público y cualquier otro personaje presente.</dd>
+  <dt>aparte</dt>
+  <dd>En las obras dramáticas, corresponde a cuando un personaje comparte un comentario solo con la audiencia para dar efecto cómico o dramático. Suele ser un sentimiento, un pensamiento o información adicional.</dd>
+</dl>
+
+ +

Los estilos predeterminados del navegador mostrarán listas de descripciones con las descripciones sangradas un poco más que los términos.

+ +

{{ EmbedLiveSample('listas-de-descripciones-ejemplo-activo-1', '100%', '285px', '', '', 'hide-codepen-jsfiddle') }}

+ +

Ten en cuenta que un solo término puede tener múltiples descripciones, por ejemplo:

+ +
+
<dl>
+  <dt>aparte</dt>
+  <dd>En las obras dramáticas, corresponde a cuando un personaje comparte un comentario solo con la audiencia para dar efecto cómico o dramático. Suele ser un sentimiento, un pensamiento o información adicional.</dd>
+  <dd>Si la obra es impresa, es una sección de contenido que se relaciona con el tema, pero no encaja directamente en el flujo principal de contenido, de modo que se presenta por separado (a menudo en una caja de texto en el margen).</dd>
+</dl>
+
+ +

{{ EmbedLiveSample('listas-de-descripciones-ejemplo-activo-2', '100%', '193px', '', '', 'hide-codepen-jsfiddle') }}

+ +

Aprendizaje activo: Marcar un conjunto de definiciones

+ +

Es hora de practicar las listas de descripciones; agrega elementos al texto sin formato en el campo Código editable para que aparezca como una lista de descripción en el campo Salida en vivo. Puedes usar tus propios términos y descripciones si lo deseas.

+ +

Si cometes un error, siempre puedes restablecer el código anterior pulsando el botón Restablecer. Si te quedas realmente encallado, pulsa el botón Mostrar solución para ver una buena propuesta.

+ + + +

{{ EmbedLiveSample('Código_reproducible', 700, 350, "", "", "hide-codepen-jsfiddle") }}

+ +

Citas

+ +

HTML también dispone de elementos para el marcado de citas; cual elemento utilices depende de si estás marcando la cita como un bloque o como un elemento en línea.

+ +

Cita en bloque independiente (blockquote)

+ +

Si una sección de contenido a nivel de bloque (ya sea un párrafo, varios párrafos, una lista, etc.) se cita en otro lugar, debes envolverla dentro de un elemento {{HTMLElement("blockquote")}} para indicarlo, e incluye una URL que apunte a la fuente de la cita dentro de un atributo {{HTMLAttrxRef("cite", "blockquote")}}. Por ejemplo, el siguiente marcado tomado de la página del elemento <blockquote> de MDN:

+ +
<p>El <strong>elemento HTML <code>&lt;blockquote&gt;</code></strong> (o <em>elemento HTML de cita
+en bloque independiente</em>) indica que el texto al que delimita es una cita ampliada.</p>
+ +

Para convertir esto en una cita en bloque independiente, simplemente harías lo siguiente:

+ +
+
<p>A continuación se muestra una cita en bloque independiente...</p>
+<blockquote cite="https://developer.mozilla.org/es/docs/Web/HTML/Element/blockquote">
+  <p>El <strong>elemento HTML <code>&lt;blockquote&gt;</code></strong> (o <em>elemento HTML de cita
+  en bloque independiente</em>) indica que el texto al que delimita es una cita ampliada.</p>
+</blockquote>
+
+ +

El estilo predeterminado del navegador lo mostrará como un párrafo con sangría, para indicar que se trata de una cita; el párrafo anterior a la cita sirve para demostrarlo.

+ +

{{EmbedLiveSample('blockquote-ejemplo-en-vivo', '100%', '117px', '', '', 'hide-codepen-jsfiddle')}}

+ +

Citas en línea

+ +

Las citas en línea funcionan exactamente de la misma manera, excepto que usan el elemento {{HTMLElement("q")}}. Por ejemplo, el siguiente fragmento de marcado contiene una cita <q> de la página MDN:

+ +
<p>El elemento de cita — <code>&lt;q&gt;</code> — se <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">utiliza en
+para citas breves que no requieren saltos de párrafo.</q></p>
+ +

El estilo predeterminado del navegador lo representará como texto normal entre comillas para indicar una cita, así:

+ +

{{ EmbedLiveSample('Citas_en_línea', '100%', '78px', '', '', 'hide-codepen-jsfiddle')}}

+ +

Citas

+ +

El contenido del atributo {{HTMLAttrxRef("cite", "blockquote")}} suena útil, pero desafortunadamente los navegadores, lectores de pantalla, etc. no hacen mucho con él. No hay forma de hacer que el navegador muestre el contenido de cite sin escribir tu propia solución usando JavaScript o CSS. Si deseas que la fuente de la cita esté disponible en la página, lo debes hacer en el texto a través de un enlace o de alguna otra forma apropiada.

+ +

Hay un elemento {{HTMLElement("cite")}}, pero está destinado a contener el título del recurso que se cita, p. ej. el nombre del libro. Sin embargo, no hay razón por la que no puedas vincular el texto dentro de <cite> a la fuente de la cita de alguna manera:

+ +
<p>De acuerdo con <a href="https://developer.mozilla.org/es/docs/Web/HTML/Element/blockquote">
+<cite>página de citas en bloque independiente de MDN</cite></a>:
+</p>
+
+<blockquote cite="https://developer.mozilla.org/es/docs/Web/HTML/Element/blockquote">
+  <p>El <strong>elemento HTML <code>&lt;blockquote&gt;</code></strong> (o <em>elemento HTML de cita
+  en bloque independiente</em>) indica que el texto al que delimita es una cita ampliada.</p>
+</blockquote>
+
+<p>El elemento de cita — <code>&lt;q&gt;</code> — se <q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">utiliza en
+citas breves que no requieren saltos de párrafo.</q> -- <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">
+<cite>página q de MDN</cite></a>.</p>
+ +

Las citas se escriben en cursiva de forma predeterminada.

+ +

{{ EmbedLiveSample('Citas_2', '100%', '179px', '', '', 'hide-codepen-jsfiddle') }}

+ +

Aprendizaje activo: ¿Quién dijo eso?

+ +

¡Es hora de otro ejemplo de aprendizaje activo! En este ejemplo, nos gustaría que:

+ +
    +
  1. Conviertas el párrafo del medio en una cita en bloque independiente, que incluya un atributo cite.
  2. +
  3. Conviertas "La necesidad de eliminar el diálogo interno negativo" en el tercer párrafo en una cita en línea e incluya un atributo cite.
  4. +
  5. Envuelvas el título de cada fuente en etiquetas <cite> y conviertas cada una en un enlace a esa fuente.
  6. +
+ +

Las fuentes de citación que necesitas son:

+ + + +

Si cometes un error, siempre puedes restablecer el código anterior pulsando el botón Restablecer. Si te quedas realmente encallado, pulsa el botón Mostrar solución para ver una buena propuesta.

+ + + +

{{ EmbedLiveSample('Código_reproducible_2', 700, 450, "", "", "hide-codepen-jsfiddle") }}

+ +

Abreviaturas

+ +

Otro elemento bastante común que encontrarás cuando busques en la Web es {{HTMLElement("abbr")}} — se usa para envolver una abreviatura o acrónimo, y proporcionar una expansión completa del término (incluida dentro de un atributo {{HTMLAttrxRef("title")}}. Veamos un par de ejemplos:

+ +
+
<p>Usamos <abbr title="Lenguaje de marcado de hipertexto">HTML</abbr> para estructurar nuestros documentos web.</p>
+
+<p>Creo que el <abbr title="Reverendo"">Rev.</abbr> Green lo hizo en la cocina con la motosierra.</p>
+
+ +

Estos saldrán con un aspecto similar a este (la expansión aparecerá en una descripción emergente cuando se coloque el cursor sobre el término):

+ +

{{EmbedLiveSample('ejemplo-de-abreviaturas-en-vivo', '100%', '94px', '', '', 'hide-codepen-jsfiddle')}}

+ +
+

Nota: Hay otro elemento, {{HTMLElement("acronym")}}, que básicamente hace lo mismo que <abbr>, y se diseñó específicamente para acrónimos en lugar de las abreviaturas. Sin embargo, este ha caído en desuso — no era compatible con los navegadores ni con <abbr>, y <abbr> tiene una función tan similar que se consideró inútil conservar ambos. Solo utiliza <abbr>.

+
+ +

Aprendizaje activo: Marcar una abreviatura

+ +

Para esta simple tarea de aprendizaje activo, nos gustaría que simplemente marcaras una abreviatura. Puedes usar el ejemplo que encontrarás a continuación o reemplazarla por una de tu elección.

+ + + +

{{ EmbedLiveSample('Código_reproducible_3', 700, 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Marcar la información de contacto

+ +

HTML tiene un elemento para marcar la información de contacto — {{HTMLElement("address")}}. Este simplemente envuelve tus datos de contacto, por ejemplo:

+ +
<address>
+  <p>Chris Mills, Manchester, The Grim North, Reino Unido</p>
+</address>
+ +

También podrías incluir un marcado más complejo y otras formas de información de contacto, por ejemplo:

+ +
<address>
+  <p>
+    Chris Mills<br>
+    Manchester<br>
+    The Grim North<br>
+    Reino Unido
+  </p>
+
+  <ul>
+    <li>Tel: 01234 567 890</li>
+    <li>Email: me@grim-north.co.uk</li>
+  </ul>
+</address>
+ +

Ten en cuenta que algo como esto también estaría bien, si la página vinculada contuviera la información de contacto:

+ +
<address>
+  <p>Página escrita por <a href="../authors/chris-mills/">Chris Mills</a>.</p>
+</address>
+ +

Superíndice y subíndice

+ +

En ocasiones, necesitarás utilizar superíndice y subíndice al marcar elementos como fechas, fórmulas químicas y ecuaciones matemáticas para que tengan el significado correcto. Los elementos {{HTMLElement("sup")}} y {{HTMLElement("sub")}} se ocupan de ello. Por ejemplo:

+ +
<p>Nací el 25<sup>th</sup> de mayo de 2001.</p>
+<p>La fórmula química de la cafeína es C<sub>8</sub>H<sub>10</sub>N<sub>4</sub>O<sub>2</sub>.</p>
+<p>If x<sup>2</sup> es 9, x debe ser igual 3 o -3.</p>
+ +

La salida de este código se ve así:

+ +

{{ EmbedLiveSample('Superíndice_y_subíndice', '100%', '141px', '', '', 'hide-codepen-jsfiddle') }}

+ +

Representación del código informático

+ +

Hay una serie de elementos disponibles para marcar código informático usando HTML:

+ + + +

Veamos algunos ejemplos. Deberías intentar jugar con estos (intenta obtener una copia de nuestro archivo de ejemplo other-semantics.html):

+ +
<pre><code>var para = document.querySelector('p');
+
+para.onclick = function() {
+  alert('¡Guau!, ¡deja de apretar!');
+}</code></pre>
+
+<p>No debes utilizar elementos de presentación como <code>&lt;font&gt;</code> y <code>&lt;center&gt;</code>.</p>
+
+<p>En el ejemplo de JavaScript anterior, <var>para</var> representa un elemento de párrafo.</p>
+
+
+<p>Selecciona todo el texto con <kbd>Ctrl</kbd>/<kbd>Cmd</kbd> + <kbd>A</kbd>.</p>
+
+<pre>$ <kbd>ping mozilla.org</kbd>
+<samp>PING mozilla.org (63.245.215.20): 56 bytes de datos
+64 bytes de 63.245.215.20: icmp_seq=0 ttl=40 time=158.233 ms</samp></pre>
+ +

El código anterior se verá así:

+ +

{{ EmbedLiveSample('Representación_del_código_informático','100%',300, "", "", "hide-codepen-jsfiddle") }}

+ +

Marcar horas y fechas

+ +

HTML también proporciona el elemento {{HTMLElement("time")}} para marcar horas y fechas en un formato legible por la máquina. Por ejemplo:

+ +
<time datetime="2016-01-20">20 Enero 2016</time>
+
+ +

¿Por qué es útil esto? Bueno, hay muchas formas diferentes en que los humanos escriben las fechas. La fecha anterior se podría escribir como:

+ + + +

Pero estas diferentes formas no las pueden reconocer fácilmente las computadoras — ¿qué pasaría si quisieras tomar automáticamente las fechas de todos los eventos en una página e insertarlas en un calendario? El elemento {{HTMLElement("time")}} te permite adjuntar una fecha/hora inequívoca y legible por la máquina para este propósito.

+ +

El ejemplo básico anterior solo proporciona una fecha simple legible por la máquina, pero hay muchas otras opciones que son posibles, por ejemplo:

+ +
<!-- Fecha simple estándar -->
+<time datetime="2016-01-20">20 Enero 2016</time>
+<!-- Solo año y mes -->
+<time datetime="2016-01">Enero 2016</time>
+<!-- Solo mes y día -->
+<time datetime="01-20">20 Enero 2016</time>
+<!-- Solo tiempo, horas y minutos -->
+<time datetime="19:30">19:30</time>
+<!-- ¡También puedes hacer segundos y milisegundos! -->
+<time datetime="19:30:01.856">19:30:01.856</time>
+<!-- Fecha y hora -->
+<time datetime="2016-01-20T19:30">7.30pm, 20 Enero 2016</time>
+<!-- Fecha y hora con desplazamiento de zona horaria -->
+<time datetime="2016-01-20T19:30+01:00">7.30pm, 20 Enero 2016 es 8.30pm en Francia</time>
+<!-- Llamar a un número de semana específico -->
+<time datetime="2016-W04">La cuarta semana de 2016</time>
+
+ +

¡Pon a prueba tus habilidades!

+ +

Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Puedes encontrar más pruebas para verificar que has retenido esta información antes de continuar; consulta {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Test_your_skills:_Advanced_HTML_text", "Pon a prueba tus habilidades: Texto HTML avanzado")}}.

+ +

Resumen

+ +

Esto marca el final de nuestro estudio de la semántica del texto HTML. Ten en cuenta que lo que has visto durante este curso no es una lista exhaustiva de elementos de texto HTML — quisimos tratar de cubrir los aspectos esenciales y algunos de los más comunes que verás en la naturaleza, o al menos podrían resultarte interesantes. Para encontrar muchos más elementos HTML, puedes echarle un vistazo a nuestra {{web.link("/es/docs/Web/HTML/Element", "referencia de elementos HTML")}} (la {{web.link("/es/docs/Web/HTML/Element#Inline_text_semantics", "La sección Semántica de texto en línea")}} sería un gran lugar para comenzar). En el próximo artículo veremos los elementos HTML que usarás para estructurar las diferentes partes de un documento HTML.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/introduccion_a_html/creating_hyperlinks/index.html b/files/es/learn/html/introduccion_a_html/creating_hyperlinks/index.html new file mode 100644 index 0000000000..330bf0d7db --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/creating_hyperlinks/index.html @@ -0,0 +1,346 @@ +--- +title: Crear hipervínculos +slug: Learn/HTML/Introduccion_a_HTML/Creating_hyperlinks +tags: + - Aprender + - CodingScripting + - Guía + - HTML + - HTTP + - Novato + - Principiante + - Title + - URL + - enlace + - hiperenlaces + - hipervínculos + - href + - referencia absoluta + - referencia relativa + - título + - urls +translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}
+ +

Los hipervínculos (o enlaces) son elementos verdaderamente importantes — son los que hacen que la web sea web. Este artículo expone la sintaxis necesaria para crear un enlace, además contiene un catálogo de buenas prácticas para crearlos.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con HTML, cubierto en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started", "Empezar con HTML")}}. Aplicación de formato a texto en documentos HTML, según lo expuesto en la sección {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "fundamentos de texto HTML")}}.
Objetivo:Aprender a implementar un hipervínculo de forma efectiva y enlazar múltiples archivos.
+ +

¿Qué es un hipervínculo?

+ +

Los hipervínculos son una de las innovaciones más interesantes que ofrece la Web. Han formado parte de esta desde el principio, pero hacen que la web sea web : Los hipervínculos nos permiten vincular documentos a otros documentos o recursos, vincular a partes específicas de documentos o hacer que las aplicaciones estén disponibles en una dirección web. Prácticamente cualquier contenido web se puede convertir en un enlace que, al pulsarlo (activarlo), dirija el navegador a la dirección web a la que apunta el enlace ({{Glossary("URL")}}).

+ +
+

Nota: Una URL puede apuntar a archivos HTML, archivos de texto, imágenes, documentos de texto, archivos de audio o vídeo, y cualquier otra cosa que se pueda mostrar en la web. Si el navegador no sabe cómo manejar el archivo, te preguntará si lo quieres abrir (en cuyo caso la tarea de abrirlo y manejarlo se transferirá a la aplicación nativa instalada en el dispositivo) o si lo quieres descargar (en cuyo caso podrás ocuparte de él más tarde).

+
+ +

El sitio web de la BBC, por ejemplo, contiene una gran cantidad de enlaces que apuntan a multitud de noticias en diferentes zonas de el sitio (funcionalidad de navegación), zonas de acceso/registro (herramientas de usuario) y otras.

+ +

Portada de bbc.co.uk, que muestra muchas noticias y la funcionalidad del menú de navegación

+ +

Anatomía de un enlace

+ +

Un enlace básico se crea incluyendo el texto (o cualquier otro contenido, ve {{anch("Convertir bloques de contenido en enlaces")}}), que queramos convertir en un enlace usando un elemento ancla {{HTMLElement("a")}}, dándole un atributo {{HTMLAttrxRef("href", "a")}} (también conocido como «Hypertext Reference», «target» u objetivo) que contendrá la dirección web hacia dónde queremos que apunte el enlace.

+ +
<p>Crea un enlace a
+<a href="https://www.mozilla.org/es-ES/">la página de inicio de Mozilla</a>.
+</p>
+ +

Este código producirá el siguiente resultado:

+ +

Crea un enlace a la página de inicio de Mozilla.

+ +

Añadir información de asistencia con el atributo title

+ +

Otro atributo que posiblemente quieras agregar a tus enlaces es title. El título contiene información adicional sobre el enlace, como qué tipo de información contiene la página o cosas que debes tener en cuenta en el sitio web.

+ +
<p>Crea un enlace a
+<a href="https://www.mozilla.org/es-ES/"
+   title="El mejor lugar para encontrar más información acerca de la misión de Mozilla
+          y cómo contribuir">la página de inicio de Mozilla</a>.
+</p>
+ +

Este código producirá el siguiente resultado (el título se mostrará al pasar el ratón sobre el texto del enlace):

+ +

Crea un enlace a la página de inicio de Mozilla.

+ +
+

Nota: El título de un enlace solo será visible al pasar el ratón por encima, lo cual significa que los usuarios que naveguen usando los controles de sus teclados, o pantallas táctiles, tendrán dificultades para acceder a la información proporcionada por el título. Si la información del título es verdaderamente importante para el uso de la página, deberemos presentar el título de manera que sea accesible a todos los usuarios, por ejemplo incluyéndola como parte del texto del enlace.

+
+ +

Aprendizaje activo: crea tu propio ejemplo de enlace

+ +

Es momento del aprendizaje activo — crea un documento HTML con tu editor de código (nuestra plantilla de aprendizaje te hará la tarea más llevadera).

+ + + +

Convertir bloques de contenido en enlaces

+ +

Como hemos mencionado anteriormente, puedes convertir cualquier contenido en un enlace, incluso {{web.link("/es/docs/Learn/HTML/Getting_started#Elementos_de_bloque_y_elementos_en_línea", "Elementos de bloque y elementos en línea")}}. Si quieres convertir una imagen en un enlace, simplemente usa el elemento {{HTMLElement("a")}} encerrando el elemento {{HTMLElement("img")}} entre <a> y </a>.

+ +
<a href="https://www.mozilla.org/es-ES/">
+  <img src="mozilla-image.png" alt="Logotipo de Mozilla que dirige a la página inicial de Mozilla">
+</a>
+ +
+

Nota: Encontrarás mucho más sobre el manejo de imágenes en próximos artículos en esta web.

+
+ +

Primer acercamiento a URLs y rutas

+ +

Para comprender completamente a dónde apuntan los enlaces, necesitas conocer las URLs y las rutas. En esta sección encontrarás la información que necesitas sobre el tema.

+ +

Una localizadora uniforme de recursos (URL, de las iniciales en inglés de «Uniform Resource Locator») es simplemente una secuencia de caracteres de texto que definen donde está situado algo en la web. Por ejemplo, la página de Mozilla está ubicada en https://www.mozilla.org/es-ES/.

+ +

Las URLs utilizan rutas para encontrar los archivos. Las rutas especifican dónde se encuentra el archivo que buscas dentro del sistema de archivos. Veamos un ejemplo de una estructura de directorios (ve el directorio creating-hyperlinks).

+ +

Una estructura de directorios simple. El directorio principal se llama creating-hyperlinks y contiene dos archivos llamados index.html y contacts.html, y dos directorios llamados projects y pdfs, que contiene un archivo index.html y un archivo project-brief.pdf, respectivamente

+ +

Al directorio raíz de esta estructura de directorios lo hemos llamado creating-hyperlinks. Al trabajar en modo local en una web, habrá un directorio que contendrá toda la información. En nuestro ejemplo, dentro de la raíz, encontramos el archivo index.html y el archivo contacts.html. En una web real, index.html es el punto de entrada a la web, lo que se conoce como página de inicio.

+ +

Observamos también dos directorios dentro de nuestro directorio raíz que son: pdfs y projects. Cada uno de ellos tiene archivos en su interior — un archivo PDF (project-brief.pdf) y un archivo index.html, respectivamente. Observa que es posible tener sin problemas dos archivos index.html en un proyecto siempre y cuando se encuentren alojados en ubicaciones diferentes de nuestra estructura de archivos — muchos sitios web lo hacen. El segundo index.html será la página de inicio para la información relativa a los proyectos.

+ + + +
+

Nota: Podemos combinar más de una instancia de estas características y generar URLs más complejas, si es necesario, por ejemplo: ../../../ruta/compleja/a/mi/archivo.html.

+
+ +

Fragmentos de documento

+ +

Es posible apuntar hacia una parte concreta de un documento HTML en vez de a todo un documento. Para ello hay que asignar previamente un atributo {{HTMLAttrxRef("id")}} al elemento hacia el que apuntamos. Esto se debe hacer en el encabezado y quedará así:

+ +
<h2 id="Dirección_de_envío">Dirección de envío</h2>
+ +

Posteriormente para hacer referencia a este id concreto, lo añadiremos al final de la URL precedido por una almohadilla — veamos el ejemplo:

+ +
<p>¿Quieres mandarnos una carta? Aquí tienes nuestra <a href="contacts.html#Dirección_de_envío">Dirección de envío</a>.</p>
+ +

También podemos usar esta referencia a un fragmento de documento para apuntar hacia otra parte del mismo documento:

+ +
<p>La <a href="#Dirección_de_envío">Dirección de envío de la empresa</a> se encuentra al final de esta página.</p>
+ +

URLs absolutas y relativas

+ +

Dos términos que encontrarás en la Web son URL absoluta y URL relativa:

+ +

URL absoluta: Hace referencia a una dirección definida por su ubicación absoluta en la web, esta incluye el {{Glossary("protocol", "protocolo")}} y el {{Glossary("domain name", "nombre del dominio")}}. Por ejemplo, si subes una página de inicio index.html a un directorio llamado projects que se encuentra dentro de la raíz de un servidor web, y el dominio del sitio web es http://www.example.com, se podrá acceder a la página desde http://www.example.com/projects/index.html (o simplemente http://www.example.com/projects/, ya que la mayoría de los servidores web buscan la página de inicio index.html para cargarla por omisión si no se les especifica otra en la URL).

+ +

Una URL absoluta siempre apuntará a la misma dirección, sin importar desde dónde se utilice.

+ +

Una URL relativa: Hace referencia a una dirección que depende de la posición del archivo desde donde se utiliza — son las que vimos en la sección anterior. Por ejemplo, si desde un archivo ubicado en http://www.example.com/projects/index.html queremos enlazar hacia un archivo PDF ubicado en el mismo directorio, la URL sería simplemente el nombre del archivo (por ejemplo: project-brief.pdf) no necesitamos más información. Si el archivo PDF está situado en un subdirectorio dentro de projects llamado pdfs, la URL relativa es: pdfs/project-brief.pdf (la URL absoluta equivalente sería: http://www.example.com/projects/pdfs/project-brief.pdf).

+ +

Una URL relativa hará referencia a diferentes direcciones según dónde se encuentre el archivo desde el cual se utiliza — por ejemplo, si movemos nuestro archivo index.html del directorio projects a la raíz del sitio web (el nivel más alto, no cualquiera de los otros directorios), la URL relativa pdfs/project-brief.pdf ahora hará referencia a http://www.example.com/pdfs/project-brief.pdf, en lugar de a http://www.example.com/projects/pdfs/project-brief.pdf.

+ +

Por supuesto, la ubicación del archivo pdfs/project-brief.pdf y del directorio pdfs no cambian de repente cuando mueves el archivo index.html; esto hará que tus enlaces apunten a un sitio equivocado y no funcionarán correctamente al hacer clic en ellos. ¡Por lo tanto debes tener cuidado!

+ +

Buenas prácticas en el uso de los enlaces

+ +

Hay algunas buenas prácticas que debemos respetar cuando escribimos enlaces. Veamos cuáles son.

+ + + +

Redacción clara del enlace

+ +

Es fácil rellenar de enlaces una página, sin más. Pero esto no basta. Hay que lograr que nuestros enlaces sean accesibles para todo tipo de lectores, sin importar el contexto o las herramientas que prefieran. Por ejemplo:

+ + + +

Veamos un ejemplo concreto:

+ +

Buen texto en un enlace: Descargar Firefox

+ +
<p><a href="https://firefox.com/">
+  Descargar Firefox
+</a></p>
+ +

Mal texto en un enlace: Pulsar aquí para descargar Firefox

+ +
<p><a href="https://firefox.com/">
+  Haz clic aquí
+</a>
+para descargar Firefox</p>
+
+ +

Otras indicaciones:

+ + + +

Utiliza enlaces relativos siempre que sea posible

+ +

A partir de las indicaciones anteriores podemos llegar a pensar que es mejor utilizar referencias absolutas en todos los casos; después de todo, estas no se rompen cuando la página se traslada como ocurre con las referencias relativas. Sin embargo, debes utilizar enlaces relativos siempre que sea posible cuando enlaces a otras ubicaciones dentro del mismo sitio web. Cuando vinculas a otro sitio web, deberás utilizar un vínculo absoluto.

+ + + +

Indica claramente los recursos no HTML

+ +

Cuando damos referencias a recursos para descargarlos (como documentos en formato PDF o Word) o para reproducirlos (como archivos de audio o vídeo) o que tengan un efecto inesperado (una ventana emergente) hay que indicarlo para no confundir al usuario.

+ +

Por ejemplo:

+ + + +

Veamos algunos ejemplos, para ver qué texto puede ser aconsejable en estos casos:

+ +
<p><a href="http://www.example.com/large-report.pdf">
+  Descarga el informe de ventas (PDF, 10MB)
+</a></p>
+
+<p><a href="http://www.example.com/video-stream/">
+  Reproduce el vídeo (el flujo de datos se abre en una pestaña independiente, calidad HD)
+</a></p>
+
+<p><a href="http://www.example.com/car-game">
+  Juega al juego del automóvil (requiere Flash)
+</a></p>
+ +

Utiliza el atributo download al enlazar una descarga

+ +

Si queremos hacer referencia a una descarga en lugar de a algo que abra el navegador, disponemos del atributo download para proporcionar un nombre predeterminado al archivo a guardar. Veamos un ejemplo con un enlace a la descarga de la versión para Windows de Firefox:

+ +
<a href="https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=es-MX"
+   download="firefox-latest-64bit-installer.exe">
+  Descarga la última versión de Firefox para Windows (64 bits) (Español, es-MX)
+</a>
+ +

Aprendizaje activo: crear un menú de navegación

+ +

Para este ejercicio, deberás crear lo que se conoce como web multipágina: un menú de navegación con enlaces a distintas páginas. Esta es una manera común de crear páginas web — usamos la misma estructura en todas las páginas, incluida la que contiene el menú de navegación. Cuando los usuarios pulsen los enlaces tendrán la sensación de que están en la misma página y que solo cambia el contenido mostrado.

+ +

Tendrás que hacer copias locales, en el mismo directorio, de las cuatro siguientes páginas (revisa el directorio navigation-menu-start para el listado completo):

+ + + +

A continuación:

+ +
    +
  1. Añade una lista no ordenada en el lugar adecuado de la página, que contenga los nombres de las páginas a las que enlazas. Un menú de navegación normalmente es una lista de enlaces (links), por lo que esto es semánticamente correcto.
  2. +
  3. Convierte cada nombre en un enlace a esa página.
  4. +
  5. Copia el menú de navegación en cada una de las páginas.
  6. +
  7. En cada página, elimina solo el enlace que hace referencia a sí mismo (es confuso y no tiene sentido que una página se llame a sí misma, y la falta del enlace actúa como recordatorio de la página en la que se está en cada momento).
  8. +
+ +

El ejercicio terminado debería crear una página como la siguiente:

+ +

Un ejemplo de un menú de navegación HTML simple, con inicio, imágenes, proyectos y elementos del menú social

+ +
+

Nota: Si ahora encallas, o no estás seguro de haberlo conseguido, revisa el directorio navigation-menu-marked-up para ver la respuesta correcta.

+
+ +

Enlace a correo electrónico

+ +

Es posible crear enlaces o botones que, cuando se pulsan, abren un nuevo correo saliente en lugar de enlazar a un recurso o página. Esto se consigue con el elemento ancla {{HTMLElement("a")}} y el elemento mailto: seguido del esquema de la URL.

+ +

En su forma más básica, un enlace mailto: simplemente contiene la dirección de correo electrónico de los destinatarios. Por ejemplo:

+ +
<a href="mailto:nowhere@mozilla.org">Enviar correo electrónico a ninguna parte</a>
+
+ +

Esto da como resultado un enlace que se ve así: Enviar correo electrónico a ninguna parte.

+ +

De hecho, incluso el atributo con la dirección de correo electrónico es opcional. Si lo omites y tu ({{HTMLAttrxRef("href", "a")}} simplemente es "mailto:", aparecerá una nueva ventana de correo saliente en el gestor de correo sin la dirección del destinatario. Esto es útil cuando queremos compartir enlaces que los usuarios puedan pulsar para enviar un correo electrónico y elegir un destinatario posteriormente.

+ +

Especificar detalles

+ +

Además de la dirección de correo electrónico, puedes proporcionar otra información. De hecho, puedes incluir cualquier campo estándar contenido en el encabezado de cualquier mensaje en la URL mailto que proporciones. Los más utilizados son el «subject» (asunto), «cc» (con copia a) o «bcc» (copia oculta), y «body» (cuerpo del mensaje, que no es realmente un campo de la cabecera, pero permite especificar un mensaje breve para el nuevo correo electrónico). Cada campo y su valor se especifican como un argumento de la consulta.

+ +

Veamos un ejemplo que incluye estos campos:

+ +
<a href="mailto:nowhere@mozilla.org?cc=name2@rapidtables.com&bcc=name3@rapidtables.com&subject=The%20subject%20of%20the%20email&body=The%20body%20of%20the%20email">
+  Enviar un correo electrónico cc, bcc, asunto y cuerpo
+</a>
+ +
+

Nota: Los valores de cada campo deben tener la URL codificada, es decir, sin caracteres no imprimibles (caracteres invisibles, tabulaciones, retornos de carro y saltos de página) y espacios con codificación porcentual (%20) {{Interwiki("wikipedia", "Código porciento")}}. También hay que tener en cuenta el uso del signo de interrogación (?) para separar la URL principal de los valores de los campos, y el símbolo ampersand (&) para separar cada campo dentro del enlace mailto:. Esta es la notación de consulta URL estándar. Lee {{web.link("/es/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data#The_GET_method", "el método GET")}} para comprender mejor qué notación de consulta URL se usa comúnmente.

+
+ +

A continuación otros ejemplos de utilización de enlaces mailto:

+ + + +

¡Pon a prueba tus habilidades!

+ +

Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Encuentra más ejercicios con los que comprobar que has retenido esta información antes de seguir adelante; consulta {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Test_your_skills:_Links", "Pon a prueba tus habilidades: Enlaces")}}.

+ +

Resumen

+ +

Eso es todo en cuanto a enlaces, ¡por ahora! Volveremos a ellos más tarde en este curso cuando comencemos a usar estilos. Lo siguiente en HTML, será aprender la semántica de texto para usar algunas características avanzadas/inusuales que nos serán utilidad — Formato de texto avanzado será la próxima parada.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/introduccion_a_html/debugging_html/index.html b/files/es/learn/html/introduccion_a_html/debugging_html/index.html new file mode 100644 index 0000000000..114b93ff0f --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/debugging_html/index.html @@ -0,0 +1,171 @@ +--- +title: Depurar el HTML +slug: Learn/HTML/Introduccion_a_HTML/Debugging_HTML +tags: + - Error + - Guía + - HTML + - Principiante + - Validación + - Validador + - depurar + - programar +translation_of: Learn/HTML/Introduction_to_HTML/Debugging_HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}
+ +

Escribir HTML es fácil, pero ¿qué pasa si algo va mal y desconocemos dónde está el error de codificación? En este artículo veremos varias herramientas que nos ayudarán a arreglar errores en HTML.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con los principios básicos de HTML, como los vistos en el apartado Empezar con el HTML, Conocimientos básicos de aplicación de formato a textos con HTML y Creación de hiperenlaces.
Objetivo:Aprender el funcionamiento básico de las herramientas de depuración de problemas de código en HTML.
+ +

Depurar no debe asustarnos

+ +

Cuando escribimos cualquier tipo de código, normalmente todo va bien, hasta ese fatídico momento en el que ocurre un error, hemos hecho algo mal y el código no funciona, o no funciona del todo, no lo suficientemente bien. Por ejemplo, el dibujo siguiente muestra un error de {{glossary("compile","compilación")}} de un programa sencillo escrito en lenguaje Rust.

+ +

A console window showing the result of trying to compile a rust program with a missing quote around a string in a print statement. The error message reported is error: unterminated double quote string.En el ejemplo, el mensaje de error es fácilmente comprensible: "unterminated double quote string" (comillas sin cerrar en el texto). Si analizamos el listado de código, observamos que en println!(Hello, world!"); faltan una comillas. Pero, los mensajes de error pueden complicarse con facilidad y su interpretación ser menos sencilla a medida que los programas aumentan en tamaño, e incluso casos sencillo pueden llegar a intimidar a alguien que no sabe nada de Rust.

+ +

Sin embargo, la depuración no nos debe asustar; la clave para sentirnos cómodos con la escritura y la depuración de cualquier lenguaje o código es la familiaridad, tanto con el lenguaje como con las herramientas.

+ +

HTML y depuración

+ +

HTML no es tan complicado de entender como Rust; HTML no se compila por separado antes de que el navegador lo analice (se interpreta, no se compila). Y la sintaxis de los {{glossary("element","elementos")}} de HTML es mucho más sencilla de entender que la de cualquier lenguaje de programación real como Rust, {{glossary("JavaScript")}} o {{glossary("Python")}}. La forma en que los navegadores ejecutan HTML es más permisiva que la de los otros lenguajes, cosa que es buena y mala a la vez.

+ +

Código permisivo

+ +

¿Qué queremos decir con permisivo? Bien, normalmente cuando hacemos algo mal al codificar, suele haber dos tipos de error:

+ + + +

HTML en sí mismo no suele producir errores sintácticos porque los navegadores son permisivos con ellos; o sea, el código se sigue ejecutando ¡aun si hay errores! Los navegadores disponen de reglas internas para saber cómo interpretar los errores de marcado incorrecto que encuentran, y seguirán funcionando aunque no produzcan el resultado esperado. Esto puede también ser un problema, por supuesto.

+ +
+

Nota: La ejecución de HTML es permisiva porque cuando se creó la web por primera vez, se decidió que el hecho de permitir que la gente publicara su contenido era más importante que el hecho de que la sintaxis fuera totalmente correcta. La web no sería tan popular como lo es hoy en día si se hubiera sido más estricto desde el primer momento.

+
+ +

Aprendizaje activo: Estudio del código permisivo

+ +

Es hora de estudiar la naturaleza permisiva del código HTML por nosotros mismos.

+ +
    +
  1. En primer lugar, hagamos una copia de nuestro ejemplo-demo a depurar y guardémoslo de forma local. Está escrito para generar diversos errores que deberemos descubrir (se dice que el marcado de HTML está mal formado, en contraposición a un marcado bien formado).
  2. +
  3. A continuación, abrámoslo en un navegador; veremos lo siguiente:A simple HTML document with a title of HTML debugging examples, and some information about common HTML errors, such as unclosed elements, badly nested elements, and unclosed attributes.
  4. +
  5. No parece que esté bien; veamos el código fuente para ver qué podemos hacer (solo mostramos el contenido del <body>): +
    <h1>HTML debugging examples</h1>
    +
    +<p>What causes errors in HTML?
    +
    +<ul>
    +  <li>Unclosed elements: If an element is <strong>not closed properly,
    +      then its effect can spread to areas you didn't intend
    +
    +  <li>Badly nested elements: Nesting elements properly is also very important
    +      for code behaving correctly. <strong>strong <em>strong emphasised?</strong>
    +      what is this?</em>
    +
    +  <li>Unclosed attributes: Another common source of HTML problems. Let's
    +      look at an example: <a href="https://www.mozilla.org/>link to Mozilla
    +      homepage</a>
    +</ul>
    +
  6. +
  7. Veamos qué problemas podemos descubrir: +
      +
    • El elemento {{htmlelement("p")}} y el {{htmlelement("li")}} no tienen etiquetas de cierre. Si comprobamos el resultado, no parece que haya generado un efecto grave en la representación del lenguaje de marcado, porque es fácil deducir que donde un elemento acaba, debería comenzar otro.
    • +
    • El primer elemento {{htmlelement("strong")}} no tiene etiqueta de cierre. Este resulta ser un poco más problemático porque no es fácil deducir dónde se supone que termina el elemento. De hecho, el énfasis fuerte se ha aplicado al resto del texto.
    • +
    • Esta sección está mal anidada: <strong>strong <em>strong emphasised?</strong> what is this?</em>. No es fácil de explicar la forma en que ha sido interpretado, debido al problema anterior.
    • +
    • Al valor del atributo {{htmlattrxref("href","a")}} le faltan las comillas de cierre. Esto parece haber causado el problema más grave: el enlace ha desaparecido totalmente.
    • +
    +
  8. +
  9. Ahora veamos lo que el navegador ha mostrado en contraposición al código fuente. Para ello podemos usar las herramientas de desarrollo del navegador. Si no estamos familiarizados con el uso de estas herramientas, echemos un vistazo rápido a Descubrir las herramientas de desarrollo del navegador, y luego continuaremos.
  10. +
  11. En el inspector de objetos (DOM), puedes comprobar la apariencia de cada elemento: The HTML inspector in Firefox, with our example's paragraph highlighted, showing the text "What causes errors in HTML?" Here you can see that the paragraph element has been closed by the browser.
  12. +
  13. Vamos a explorar nuestro código en detalle con el inspector de objetos DOM para ver cómo el navegador ha arreglado nuestros errores de código HTML (lo hemos hecho con Firefox; otros navegadores modernos deberían conducir al mismo resultado): +
      +
    • Se han añadido etiquetas de cierre a los párrafos y las líneas de las listas.
    • +
    • Al no estar claro el final del elemento <strong>, el navegador lo ha aplicado individualmente a todos los bloques de texto siguientes, a cada uno le ha añadido su etiqueta strong propia, desde donde está ¡hasta el final del documento!
    • +
    • El navegador ha arreglado el anidamiento incorrecto del modo siguiente: +
      <strong>strong
      +  <em>strong emphasised?</em>
      +</strong>
      +<em> what is this?</em>
      +
    • +
    • El enlace a cuyo atributo le faltan las comillas del final ha sido ignorado. La última lista la ha dejado como sigue: +
      <li>
      +  <strong>Unclosed attributes: Another common source of HTML problems.
      +  Let's look at an example: </strong>
      +</li>
      +
    • +
    +
  14. +
+ +

Validación HTML

+ +

Con el ejemplo anterior podemos asegurarnos de que nuestro HTML está bien formado, pero ¿cómo? En el ejemplo siguiente podemos comprobar que es bastante fácil buscar entre las líneas y encontrar los errores en documentos pequeños; pero, ¿qué pasa cuando trabajamos con documentos HTML grandes y complejos?

+ +

La mejor estrategia es comenzar por pasar tu página HTML por el servicio de validación de etiquetas; fue creado y está mantenido por el W3C, organización que se encarga de definir las especificaciones de HTML, CSS y otras tecnologías web. Esta página web toma un documento HTML como entrada, lo procesa, y genera un informe de dónde están los errores en el documento.

+ +

The HTML validator homepage

+ +

Para validar el HTML, podemos proporcionar al validador una dirección web a la que apuntar, subirle un archivo HTML, o directamente introducirle el código HTML que queremos que revise.

+ +

Aprendizaje activo: Validación de un documento HTML

+ +

Vamos a probar de validar nuestro documento ejemplo.

+ +
    +
  1. Primero, cargamos el servicio de validación en una pestaña del navegador, si no lo tenemos ya.
  2. +
  3. Hacemos clic en la subpestaña Validate by Direct Input.
  4. +
  5. Copiamos el código del documento ejemplo (no solo el body) y lo pegamos en el cuadro de texto grande.
  6. +
  7. Hacemos clic en el botón Check.
  8. +
+ +

Esto debería proporcionar una lista de errores y otras informaciones:

+ +

A list of of HTML validation results from the W3C markup validation service

+ +

Interpretación de los mensajes de error

+ +

La lista de mensajes de error que nos presenta el validador suele ayudar, pero a veces, no resultan muy útiles; con un poco de práctica aprenderemos a interpretar la lista para arreglar nuestro código. Veamos los mensajes de error y su significado. Observamos que cada mensaje se presenta con un número de línea y de columna, para ayudar a localizar el error más fácilmente.

+ + + +

No debemos preocuparnos si no podemos corregir todos los mensajes de error; es práctico tratar de arreglar unos pocos errores cada vez y volver a pasar el validador para ver los que quedan. A veces, al arreglar unos cuantos se arreglan automáticamente otros muchos; con frecuencia muchos errores los causa uno solo en un efecto dominó.

+ +

Sabremos  que todos los errores están arreglados cuando veamos el mensaje siguiente:

+ +

Banner that reads "The document validates according to the specified schema(s) and to additional constraints checked by the validator."

+ +

Resumen

+ +

Pues hasta aquí una introducción al depurado de HTML, que nos proporcionará habilidades para cuando comencemos a depurar CSS, JavaScript y otros lenguajes más adelante en nuestros trabajos. Este apartado también constituye el final de la introducción al módulo de artículos de aprendizaje de HTML; ahora podemos hacer los test de prueba: el primero de los cuales está en el enlace siguiente.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

diff --git a/files/es/learn/html/introduccion_a_html/estructura/index.html b/files/es/learn/html/introduccion_a_html/estructura/index.html new file mode 100644 index 0000000000..1f5f1e315c --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/estructura/index.html @@ -0,0 +1,298 @@ +--- +title: Estructura web y documentación +slug: Learn/HTML/Introduccion_a_HTML/estructura +tags: + - CodingScripting + - Composición + - Diseño + - Formato + - Guía + - HTML + - Presentación + - Principiante + - Sitio + - Sitio Web + - bloques + - pagina + - programar + - semántica +translation_of: Learn/HTML/Introduction_to_HTML/Document_and_website_structure +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}
+ +

Además de definir partes individuales de tu página (como un párrafo o una imagen), {{Glossary("HTML")}} también dispone de elementos de bloque que se pueden utilizar para estructurar las distintas áreas de tu sito web (tal como el encabezado, el menú de navegación o la parte del contenido principal. En este artículo veras cómo planificar una estructura básica de página web y escribirás el HTML que representa esa estructura.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con HTML, cubierto en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started", "Empezar con HTML")}}. Aplicación de formato a texto en documentos HTML, según lo expuesto en la sección {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Fundamentos de texto HTML")}}. Funcionamiento de los hipervínculos, cubierto en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Crear hipervínculos")}}.
Objetivo:Aprender a estructurar tu documento usando atributos semánticos y construir la estructura de una página web sencilla.
+ +

Partes básicas de un documento

+ +

Las páginas web pueden y se deben diferenciar las unas de las otras, pero todas tienden a contener elementos comunes parecidos, a menos que estén destinadas a mostrar un vídeo o un juego a pantalla completa, o que formen parte de un proyecto artístico concreto o, simplemente, que estén mal estructuradas; estos elementos comunes son:

+ +
+
encabezado:
+
Normalmente formado por una gran franja que cruza la parte superior de la página con un gran título, un logotipo y quizás un lema. Esta parte suele permanecer invariable mientras navegas entre las páginas de un mismo sitio web.
+
barra de navegación:
+
Son los enlaces a las secciones principales del sitio web. Normalmente está formada por un menú con botones, enlaces o pestañas. Al igual que el encabezado, este contenido suele permanecer invariable en las diferentes páginas del sitio; tener un menú inconsistente en tu página web conducirá a los usuarios a la confusión y frustración. Muchos diseñadores web consideran que el menú de navegación forma parte del encabezado y que no posee un componente individual, aunque no es necesario que sea así; de hecho, algunos argumentan que tener ambos componentes por separado es mejor por motivos de {{web.link("/es/docs/Learn/Accessibility", "accesibilidad")}} porque los lectores de pantalla pueden leer mejor ambos elementos si están separados.
+
contenido principal:
+
Es la gran parte central de la página y contiene la mayor parte del contenido particular de una página web concreta; por ejemplo, el video que quieres ver, la narración que quieres leer, el mapa que quieres consultar, los titulares de las noticias, etc. ¡Esta es la parte que definitivamente debe variar mucho de una página a otra de tu sitio web!
+
barra lateral:
+
Suele incluir algún tipo de información adicional, enlaces, citas, publicidad, etc. Normalmente está relacionada con el contenido principal de la página (por ejemplo, en una página de noticias, la barra lateral podría contener la biografía del autor o enlaces a artículos relacionados), pero en otras ocasiones encontraras elementos recurrentes como un menú de navegación secundario.
+
pie de página:
+
Es la parte inferior de la página, que generalmente contiene la letra pequeña, el copyright o la información de contacto. Es el sitio donde se coloca la información común (al igual que en el encabezado), pero esta información no suele ser tan importante o es secundaria con respecto a la página en sí misma. El pie también se suele usar para propósitos {{Glossary("SEO")}}, e incluye enlaces de acceso rápido al contenido más popular.
+
+ +

Una página web «típica» se podría parecer a esta:

+ +

Un ejemplo de estructura de sitio web simple con un encabezado principal, menú de navegación, contenido principal, barra lateral y pie de página.

+ +

HTML para dar estructura al contenido

+ +

El ejemplo no es muy atractivo, pero puede servir para ilustrar un ejemplo de diseño de una página web típica. Puedes encontrar sitios con más columnas, algunas mucho más complejas, pero esta servirá para hacerte una idea general sobre el tema. Con el CSS adecuado podrás usar muchos más elementos para decorar las distintas secciones y conseguir que queden como deses, pero como se comentó anteriormente, necesitas respetar ciertas normas semánticas, y utilizar el elemento adecuado para cada tipo de sección.

+ +

La parte visual no lo es todo. Utilizarás diferentes fuentes y colores para llamar la atención de los usuarios sin discapacidad visual de las partes más importantes del contenido, como el menú de navegación y sus enlaces correspondientes, pero ¿qué ocurre con los usuarios con discapacidad visual que no pueden distinguir los colores llamativos o el tamaño grande de las fuentes?

+ +
+

Nota: Los daltónicos representan alrededor del 4% de la población mundial (aproximadamente 1 de cada 12 hombres y 1 de cada 200 mujeres son daltónicos). Los invidentes y las personas con discapacidad visual representan aproximadamente el 4-5% de la población mundial (en 2012 había {{Interwiki("wikipedia", "Discapacidad visual")}} 285 millones de personas con alguna de estas características en el mundo, mientras que el total de la población estaba {{Interwiki("wikipedia", "World_human_population#/media/File:World_population_history.svg", "alrededor de los 7,000 millones")}}.

+
+ +

En tu código HTML puedes crear secciones de contenido basadas en su funcionalidad — puedes usar elementos que representen sin ambigüedad las diferentes secciones de contenido descritas, de forma que las tecnologías de accesibilidad y los lectores de pantalla puedan reconocer esos elementos y asistir en tareas como «encontrar el menú de navegación», o «encontrar el contenido principal». Como se mencionó anteriormente en el curso, hay una serie de {{web.link("/es/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals#Por_qué_necesitamos_estructura", "consecuencias por no usar la estructura de elementos y semántica adecuada para hacer el trabajo correctamente")}}.

+ +

HTML dispone de etiquetas adecuadas que puedes usar para establecer estas secciones semánticas, por ejemplo:

+ + + +

Aprendizaje activo: El código del ejemplo anterior

+ +

El ejemplo de página web que se muestra arriba se consigue a partir del siguiente código (disponible en el repositorio Github). Observa el ejemplo anterior, y a continuación échale un vistazo al código de abajo para identificar las secciones marcadas en el ejemplo.

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+
+    <title>El título de mi página</title>
+    <link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Sonsie+One" rel="stylesheet" type="text/css">
+    <link rel="stylesheet" href="style.css">
+
+    <!-- las tres siguientes líneas son un truco para obtener elementos semánticos de HTML5 que funcionan en versiones de Internet Explorer antiguas -->
+    <!--[if lt IE 9]>
+      <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
+    <![endif]-->
+  </head>
+
+  <body>
+    <!-- Aquí empieza el encabezado principal que se mantendrá en todas las páginas del sitio web -->
+
+    <header>
+      <h1>Encabezado</h1>
+    </header>
+
+    <nav>
+      <ul>
+        <li><a href="#">Inicio</a></li>
+        <li><a href="#">Nuestro equipo</a></li>
+        <li><a href="#">Proyectos</a></li>
+        <li><a href="#">Contacto</a></li>
+      </ul>
+
+       <!-- Un formulario de búsqueda es una forma no-lineal de hacer búsquedas en un sitio web. -->
+
+       <form>
+         <input type="search" name="q" placeholder="Buscar">
+         <input type="submit" value="¡Vamos!">
+       </form>
+     </nav>
+
+    <!-- Aquí está el contenido principal de nuestra página -->
+    <main>
+
+      <!-- Contiene un artículo -->
+      <article>
+        <h2>Título del artículo</h2>
+
+        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.</p>
+
+        <h3>Subsección</h3>
+
+        <p>Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor.</p>
+
+        <p>Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus, enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.</p>
+
+        <h3>Otra subsección</h3>
+
+        <p>Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum soclis natoque penatibus et manis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+
+        <p>Vivamus fermentum semper porta. Nunc diam velit, adipscing ut tristique vitae sagittis vel odio. Maecenas convallis ullamcorper ultricied. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, is fringille sem nunc vet mi.</p>
+      </article>
+
+      <!-- el contenido aparte también se puede anidar dentro del contenido principal -->
+      <aside>
+        <h2>Relacionado</h2>
+
+        <ul>
+          <li><a href="#">Oh, me gusta estar junto al mar</a></li>
+          <li><a href="#">Oh, me gusta estar junto al mar</a></li>
+          <li><a href="#">Aunque en el norte de Inglaterra</a></li>
+          <li><a href="#">Nunca deja de llover</a></li>
+          <li><a href="#">Oh, bueno...</a></li>
+        </ul>
+      </aside>
+
+    </main>
+
+    <!-- Y aquí está nuestro pie de página principal que se utiliza en todas las páginas de nuestro sitio web -->
+
+    <footer>
+      <p>©Copyright 2050 de nadie. Todos los derechos revertidos.</p>
+    </footer>
+
+  </body>
+</html>
+ +

Tómate tu tiempo para revisar el código y comprenderlo — Los comentarios en el código también te ayudarán a entenderlo. No te pedimos que hagas mucho más en este artículo, porque la clave para entender el diseño del documento es escribir una estructura HTML conocida y posteriormente desarrollar su apariencia con CSS. Estudiaremos el diseño CSS como parte del tema CSS.

+ +

Elementos de diseño HTML en detalle

+ +

Es bueno entender el significado global de todos los elementos definitorios de las secciones HTML en detalle; es algo en que trabajarás gradualmente a medida que comiences a tener más experiencia en el desarrollo web. En el enlace {{web.link("/es/docs/Web/HTML/Element", "referencia de elementos HTML")}} podemos entrar en un gran nivel de detalle. Por el momento, estas son las definiciones principales que deberíamos tratar de entender:

+ + + +

Envolturas no semánticas

+ +

A veces hay situaciones en las que no encuentras un elemento semántico adecuado para agrupar ciertos elementos o englobar cierto contenido. Podrías querer agrupar ciertos elementos para referirte a ellos como una entidad que comparta cierto {{Glossary("CSS")}} o {{Glossary("JavaScript")}}. Para casos como esos, HTML dispone del elemento {{HTMLElement("div")}} y del elemento {{HTMLElement("span")}}. Preferentemente estos elementos se deberán utilizar con sus atributos ({{HTMLAttrxRef('class')}}), para conferirles algún tipo de etiquetado que permita determinarlos con facilidad.

+ +

{{HTMLElement("span")}} es un elemento no-semántico que se utiliza en el interior de una línea. Se utiliza cuando no se nos ocurre el uso de ningún otro elemento semántico de texto en el que incluir el contenido, o si no se desea añadir ningún significado específico. Por ejemplo:

+ +
<p>El rey volvió ebrio a su habitación alrededor de la 01:00, y sin duda la cerveza no le ayudaba
+cuando cruzó tambaleante la puerta <span class="editor-note">[nota del editor: en este instante de la
+representación, deberían atenuarse las luces]</span>.</p>
+ +

En este caso, la nota del editor solo proporciona información extra para el director de la obra; se supone que estos elementos no incluyen contenido extra importante. Para los usuarios sin discapacidad visual, quizás debamos usar CSS para diferenciar sutilmente estas notas del texto principal.

+ +

{{HTMLElement("div")}} es un elemento de bloque no-semántico; lo utilizaras cuando no se te ocurra el uso de otro elemento semántico mejor, o si no deseas añadir ningún significado concreto. Por ejemplo, imagina un carrito de compras que puedes pulsar en cualquier momento durante tu estancia en una tienda virtual:

+ +
<div class="shopping-cart">
+  <h2>Carrito de compras</h2>
+  <ul>
+    <li>
+      <p><a href=""><strong>Pendientes de plata</strong></a>: $99.95.</p>
+      <img src="../products/3333-0985/" alt="Pendientes de plata">
+    </li>
+    <li>
+      ...
+    </li>
+  </ul>
+  <p>Importe total: $237.89</p>
+</div>
+ +

Este no es un elemento lateral (<aside>) porque no necesariamente está relacionado con el contenido principal de la página (en realidad quieres que se pueda ver desde cualquier página). Ni siquiera se puede incluir en una sección (<section>) porque su contenido no forma parte del contenido principal de la página. Por lo tanto, un elemento <div> es el adecuado en este caso. Hemos incluido un encabezado para indicar a los lectores de pantalla donde van a encontrarlo.

+ +
+

Atención: Los elementos div son tan prácticos y simples que es fácil usarlos en exceso. Como no conllevan valor semántico, enmarañan el código HTML. Debemos tener cuidado de usarlos solo cuando no halles una solución mejor y reducir su uso al mínimo, porque de otro modo complicarás el mantenimiento y actualización de los documentos.

+
+ +

Saltos de línea y líneas horizontales

+ +

Dos elementos que debes conocer y utilizarás ocasionalmente son {{HTMLElement("br")}} y {{HTMLElement("hr")}}:

+ +

El elemento {{HTMLElement("br")}} genera un salto de línea en un párrafo; es la única manera de representar series de líneas cortas, como una dirección postal o un poema. Por ejemplo:

+ +
+
<p>Había una vez un hombre llamado O'Dell<br>
+A quién le encantaba escribir HTML<br>
+Pero su estructura era mala, su semántica era triste<br>
+y su marcado no se interpretó muy bien.</p>
+
+ +

Sin el elemento {{HTMLElement("br")}}, todo el párrafo se habría presentado como una sola línea larga (como ya hemos dicho con anterioridad en este curso, {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started#Los_espacios_en_blanco_en_HTML", "HTML ignora la mayoría del espacio en blanco")}}); con estos elementos {{HTMLElement("br")}} en el código, las líneas quedan:

+ +

{{EmbedLiveSample('line-break-live-sample', '100%', '125px', '', '', 'hide-codepen-jsfiddle')}}

+ +

Los elementos {{HTMLElement("hr")}} generan una regla horizontal en el documento que denota un cambio en la temática del texto (como un cambio de tema o de escena). Visualmente tiene el aspecto de una línea horizontal. Por ejemplo:

+ +
+
<p>Ron fue acorralado en una esquina por las bestias abisales que merodeaban. Asustado, pero decidido a proteger a sus amigos, levantó su varita y se preparó para la batalla, con la esperanza de que su llamada de socorro hubiera llegado a alguien.</p>
+<hr>
+<p>Mientras tanto, Harry estaba sentado en su casa, mirando su declaración de regalías y pensando en cuándo saldría la próxima serie derivada, cuando de pronto voló por su ventana una carta de socorro y aterrizó en su regazo. La leyó vagamente y suspiró; "Será mejor que vuelva al trabajo entonces", reflexionó.</p>
+
+ +

Quedará así:

+ +

{{EmbedLiveSample('Ejemplo_en_vivo_línea_horizontal', '100%', '185px', '', '', 'hide-codepen-jsfiddle')}}

+ +

Planificación de una página web sencilla

+ +

Una vez has planificado el contenido de una página web sencilla, el paso lógico siguiente es intentar trabajar en el contenido para todo el sitio web, las páginas que necesitas y la forma de disponer las conexiones entre ellas para producir la mejor experiencia de usuario a los visitantes. Esto se conoce con el nombre de ({{Glossary("Arquitectura de la información")}}). Una web grande y compleja necesitará mucha planificación, pero para una web sencilla compuesta por unas cuantas páginas, el proceso puede ser sencillo, ¡y divertido!.

+ +
    +
  1. Ten en cuenta que habrá varios elementos comunes en muchas (si no en todas las) páginas, tal como el menú de navegación y el contenido del pie de página. Si la web está dedicada a un negocio, por ejemplo, sería una buena idea disponer de la información de contacto en el pie de página en todas las páginas. Anota lo que deseas tener en común en cada página. las características comunes del sitio de viajes para ir en cada página: título y logotipo, contacto, derechos de autor, términos y condiciones, selección de idioma, política de accesibilidad
  2. +
  3. A continuación, esboza un esquema sencillo de cuál podría ser la estructura deseada de la apariencia de cada página (podría ser algo tan sencillo como el siguiente dibujo). Anota los bloques principales. Un diagrama simple de una estructura de sitio de ejemplo, con un encabezado, un área de contenido principal, dos barras laterales opcionales y un pie de página
  4. +
  5. Ahora, elabora una lista completa con todo el resto del contenido de tu sitio web que no sea común a todas las páginas. Una larga lista de todas las funciones que podrías incluir en tu sitio de viajes, desde buscar, hasta ofertas especiales e información específica del país
  6. +
  7. A continuación, trata de ordenar todo este contenido por grupos, para hacerte una idea de las partes que podrían ir juntas en las diferentes páginas. Esto es muy similar a una técnica llamada {{Glossary("Clasificación de tarjetas")}}. Los elementos que deberían aparecer en un sitio de vacaciones ordenados en 5 categorías: Búsqueda, Especiales, Información específica del país, Resultados de búsqueda y Compra cosas
  8. +
  9. Ahora trata de esquematizar un mapa de tu sitio — dibuja un globo para cada página de tu sitio web y dibuja líneas que identifiquen el flujo de datos entre las distintas páginas. La página de inicio normalmente estará ubicada en el centro y enlazará con el resto de páginas; la mayoría de las páginas de una web sencilla estarán enlazadas desde el menú de navegación principal, aunque puede haber excepciones. También puedes incluir notas sobre cómo se pueden presentar las cosas. Un mapa del sitio que muestra la página de inicio, la página del país, los resultados de búsqueda, la página de ofertas especiales, la página de pago y la página de compra
  10. +
+ +

Aprendizaje activo: Creación de un mapa del sitio web

+ +

Intenta llevar a cabo el ejercicio anterior para crear tu propia página web. ¿Qué contenido le vas a dar a tu sitio web?

+ +
+

Nota: Guarda este esquema para utilizarlo más adelante.

+
+ +

¡Pon a prueba tus habilidades!

+ +

Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Puedes encontrar una evaluación detallada que pruebe estas habilidades al final del módulo; consulta {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Estructurar el contenido de una página")}}. ¡Recuerda leer primero el siguiente artículo de la serie y no solo saltarlo!

+ +

Resumen

+ +

En este punto, deberías tener una mejor idea sobre cómo estructurar una página/sitio web. En el último artículo de este módulo, se explica cómo depurar HTML.

+ +

Ve también

+ + + +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML")}}

+ +

En este módulo

+ + diff --git "a/files/es/learn/html/introduccion_a_html/estructuraci\303\263n_de_una_p\303\241gina_de_contenido/index.html" "b/files/es/learn/html/introduccion_a_html/estructuraci\303\263n_de_una_p\303\241gina_de_contenido/index.html" new file mode 100644 index 0000000000..686940212e --- /dev/null +++ "b/files/es/learn/html/introduccion_a_html/estructuraci\303\263n_de_una_p\303\241gina_de_contenido/index.html" @@ -0,0 +1,105 @@ +--- +title: Estructuración de una Página de contenido +slug: Learn/HTML/Introduccion_a_HTML/Estructuración_de_una_página_de_contenido +tags: + - Aprendizaje + - Diseño + - Escribir Código + - Estructuración + - Evaluación + - HTML + - Principiante + - Prototipado + - semántica +translation_of: Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}} 
+ +

La estructuración de una página de contenido lista para su uso mediante CSS es una habilidad muy importante para dominar, por lo que en esta evaluación  verá  su capacidad para pensar en cómo  podría finalizar una página  buscando y eligiendo la semántica estructural adecuada para construir un diseño en la parte superior.

+ +
+
 
+
+ + + + + + + + + + + + +
Prerequisitos:Antes de intentar esta evaluación, usted debería haber trabajado ya en el resto del curso, con un énfasis particular en la Estructura del Documento y del Sitio Web..
Objetivo:Probar el conocimiento de las estructuras de páginas web y cómo representar un prototipado de diseño prospectivo en el marcado.
+ +

Punto de partida

+ +

Para comenzar esta evaluación, debería tomar el   archivo zip  que contiene todos los activos de inicio. El archivo zip contiene:

+ + + +

Crée el ejemplo en su ordenador personal, o como alternativa utilize un sitio como JSBin o Thimble para hacer su evaluación.

+ +

Breve Proyecto

+ +

Para este proyecto, su tarea es tomar el contenido de la página principal de un sitio web de observación de aves y añadir elementos estructurales a la misma para que pueda tener un diseño de página aplicado a ella. Necesita tener:

+ + + +

Debe agregar una presentación adecuada para:

+ + + +

También debería:

+ + + +

Consejos

+ + + +

Ejemplo

+ +

La siguiente captura de pantalla muestra un ejemplo de cómo podría verse la letra después de haber sido marcada.

+ +

The finished example for the assessment; a simple webpage about birdwatching, including a heading of "Birdwatching", bird photos, and a welcome message

+ +

Evaluación

+ +

Si está siguiendo esta evaluación como parte de un curso organizado, debe ser capaz de dar su trabajo a su maestro / mentor para el marcado. Si usted está aprendiendo por si mismo, entonces  puede obtener la guía de marcado con bastante facilidad preguntando sobre ello en la lista de correo  dev-mdc , o en el canal IRC #mdn  en Mozilla IRC. Pruebe a hacer el ejercicio primero - ¡No hay nada que ganar por hacer trampa!

+ +

{{PreviousMenu("Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Learn/HTML/Introduction_to_HTML")}}

+ +
+ + +
 
+ +
 
+
diff --git a/files/es/learn/html/introduccion_a_html/index.html b/files/es/learn/html/introduccion_a_html/index.html new file mode 100644 index 0000000000..64c70649cb --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/index.html @@ -0,0 +1,77 @@ +--- +title: Introducción a HTML +slug: Learn/HTML/Introduccion_a_HTML +tags: + - CodingScripting + - Enlaces + - Estructura + - HTML + - Introducción a HTML + - Texto + - semántica +translation_of: Learn/HTML/Introduction_to_HTML +--- +
{{LearnSidebar}}
+ +

En su corazón, {{glossary("HTML")}} es un lenguaje muy sencillo compuesto de {{Glossary("Element", "elementos")}}, que se pueden aplicar a piezas de texto para darles un significado diferente en un documento (¿Esto es un párrafo? ¿Esto es una lista con viñetas? ¿Esto es parte de una tabla?), estructura un documento en secciones lógicas (¿Tiene una cabecera? ¿Tres columnas de contenido? ¿Un menú de navegación?), e incrusta contenido como imágenes y vídeos en una página. Este módulo introducirá los dos primeros de estos, e introduce conceptos fundamentales y la sintaxis que necesitas para entender HTML.

+ +
+

¿Quieres transformarte en un desarrollador de la interfaz de usuario web?

+ +

Hemos elaborado un curso que incluye toda la información esencial que necesitas para trabajar hacia tu objetivo.

+ +

Empieza aquí

+
+ +

Prerrequisitos

+ +

Antes de empezar este módulo, no necesitas conocimientos previos de HTML, pero deberías estar, por lo menos, familiarizado con el uso básico de computadoras, y usar la Web pasivamente (es decir, sólo revisándola y consumiendo el contenido). Debes tener configurado un entorno de trabajo básico (como se detalla en {{web.link("/es/docs/Learn/Getting_started_with_the_web/Installing_basic_software", "Instalación de software básico")}}), y comprender cómo crear y administrar archivos (como se detalla en {{web.link("/es/docs/Learn/Getting_started_with_the_web/Dealing_with_files", "Manejo de archivos")}}). Ambos son parte de nuestro módulo completo {{web.link("/es/docs/Learn/Getting_started_with_the_web", "Introducción a la web")}} para principiantes.

+ +
+

Nota: Si estás trabajando en una computadora, tablet u otro dispositivo en donde no tengas la capacidad de crear tus propios archivos, podrías probar (en su mayoría) el código de los ejemplos en un programa para escribir código en línea como JSBin o Glitch.

+
+ +

Guías

+ +

Este módulo contiene los siguientes artículos, que te llevarán a través de toda la teoría básica de HTML, y te proporcionarán una amplia oportunidad de probar algunas habilidades.

+ +
+
Empezar con HTML
+
Cubre las bases absolutas de HTML, para que puedas empezar — definimos elementos, atributos, y todas los otros términos importantes que puedas haber escuchado, y en donde encajan en el lenguaje. También mostramos cómo está estructurado un elemento HTML, cómo está estructurada una página HTML típica, y explica otras características importantes. En el camino, vamos a tener un juego con algo de HTML, ¡para alimentar tu intereses!
+
¿Qué hay en la cabecera? Metadatos en HTML
+
La cabecera de un documento HTML es la parte que no se muestra en el navegador web cuando se carga una página. Esta contiene información como el título ({{htmlelement("title")}}) de la página, enlaces a {{glossary("CSS")}} (si quieres estilizar tu contenido HTML con CSS), enlaces a favicons personalizados, y metadatos (que son los datos sobre el HTML, como quién lo escribió, y palabras clave que describen el documento).
+
Fundamentos de texto HTML
+
Uno de los principales trabajos de HTML es darle significado al texto (también conocido como semántica) para que el navegador sepa cómo mostrarlo correctamente. Este artículo trata cómo usar HTML para convertir un bloque de texto en una estructura de encabezados y párrafos, agregar énfasis o importancia a las palabras, crear listas y más.
+
Creando hipervínculos
+
Los hipervínculos realmente son importantes — estos son los que hacen la Web. Este artículo muestra la sintaxis requerida para hacer un enlace, y explica las mejores prácticas sobre enlaces.
+
Formateo de texto avanzado
+
Hay muchos otros elementos en HTML para formatear texto, que no hemos tratado en los artículos {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "fundamentos de texto HTML")}}. Los siguientes elementos son menos conocidos, pero sigue siendo útil conocerlos. Aquí aprenderás sobre el marcado de citas, listas de descripción, código de computadoras y otros textos relacionados, subíndices y superíndices, información de contacto, y mucho más.
+
{{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure", "Estructura web y documentación")}}
+
Así como definimos las partes individuales de tu página (como "un párrafo" o "una imagen"), HTML también se usa para definir las áreas de tu sitio web (como "la cabecera", "el menú de navegación", "la columna de contenido principal"). Este artículo trata sobre cómo planear una estructura básica del sitio web, y escribir el HTML para representar esa estructura.
+
Depurar HTML
+
Escribir HTML está bien, pero ¿Qué pasa si algo está mal, y no puedes encontrar en dónde está el error en el código? Este artículo introducirá algunas herramientas que te podrán ayudar.
+
+ +

Evaluaciones

+ +

Las siguientes evaluaciones probarán tu entendimiento de las bases de HTML cubiertas en las guías anteriores.

+ +
+
{{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Marking_up_a_letter", "Marcando para una carta")}}
+
Todos aprendemos a escribir una carta, tarde o temprano; ¡Este también es un ejemplo útil para poner a prueba nuestras habilidades de formato de texto! Así que en esta evaluación se te dará una carta a la cual le tendrás que dar un marcado HTML.
+
{{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Estructuración del contenido de una página")}}
+
Esta evaluación prueba tu capacidad para usar HTML para estructurar el contenido de una sencilla página, esta tiene una cabecera, pie de página, menú de navegación, contenido principal, y una barra lateral.
+
+ +

Ve también

+ +
+
Bases de la alfabetización Web 1
+
Un curso excelente de la fundación Mozilla que explora y pone a prueba muchas de las habilidades sobre las cuales hablamos en el módulo de Introducción a HTML. Los estudiantes se familiarizan con la lectura, escritura y participan de la web en este módulo de seis partes. Descubre los fundamentos de la web a través de la producción y colaboración.
+
+ +
+

Retroalimentación

+ +

Ayúdanos a mejorar nuestras guías y tutoriales como esta respondiendo {{web.link("https://www.surveygizmo.com/s3/4871248/MDN-Guides-Survey", "nuestra encuesta aquí")}}.

+
diff --git a/files/es/learn/html/introduccion_a_html/iniciar/index.html b/files/es/learn/html/introduccion_a_html/iniciar/index.html new file mode 100644 index 0000000000..c05aa6a9f0 --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/iniciar/index.html @@ -0,0 +1,767 @@ +--- +title: Empezar con HTML +slug: Learn/HTML/Introduccion_a_HTML/iniciar +tags: + - Atributos + - Elemento + - Guía + - HTML + - Principiante + - comentários +translation_of: Learn/HTML/Introduction_to_HTML/Getting_started +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML")}}
+ +

En este artículo vamos a exponer lo más básico del HTML. Para comenzar definiremos elementos, atributos y el resto de términos importantes que quizá ya te suenen y qué función cumplen dentro del lenguaje. También explica dónde encajan estos en HTML. Aprenderás cómo se estructuran los elementos HTML, cómo se estructura una página HTML típica y otras características básicas importantes del lenguaje. Por el camino, también iremos practicando con algo de HTML.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, {{web.link("/es/docs/Learn/Getting_started_with_the_web/Installing_basic_software", "tener instalado el software básico")}} y conocimientos básicos de cómo {{web.link("/es/docs/Learn/Getting_started_with_the_web/Dealing_with_files", "trabajar con archivos")}}.
Objetivo:Familiarizarte con el lenguaje HTML, y adquirir algo de práctica escribiendo unos pocos elementos HTML.
+ +

¿Qué es el HTML?

+ +

{{Glossary("HTML")}} ("Hypertext Markup Language") no es un lenguaje de programación. Es un lenguaje de marcado que le dice a los navegadores web cómo estructurar las páginas web que estás visitando. Puede ser tan complejo o tan simple como desee el desarrollador web. El HTML consiste en una serie de {{Glossary("Element", "elementos")}}, que puedes utilizar para encerrar, delimitar o marcar diferentes partes del contenido para hacer que aparezcan de una cierta manera, o actúen de determinada forma. Las {{Glossary("Tag", "etiquetas")}} que delimitan un fragmento de contenido pueden hacer que dicho contenido enlace con otra página, ponga una palabra en cursiva, etcétera. Por ejemplo, dada la siguiente línea de contenido:

+ +
Mi gato es muy gruñón
+ +

Si queremos que la línea sea independiente de otras, podemos especificar que es un párrafo encerrándola con una etiqueta de elemento de párrafo ({{htmlelement("p")}}):

+ +
<p>Mi gato es muy gruñón</p>
+ +
+

Nota: Las etiquetas en HTML no distinguen entre mayúsculas y minúsculas. Así que se pueden escribir tanto en mayúsculas como en minúsculas. Por ejemplo, una etiqueta {{htmlelement("title")}} se puede escribir como <title>, <TITLE>, <Title>, <TiTle>, etc., y funcionará correctamente. La mejor práctica, sin embargo, es escribir todas las etiquetas en minúsculas para mantener la coherencia y legibilidad, entre otros motivos.

+
+ +

Anatomía de un elemento HTML

+ +

Exploremos un poco el elemento párrafo:

+ +

Anatomía de los elementos HTML

+ +

Las principales partes de nuestro elemento son:

+ + + +

El elemento lo conforman la etiqueta de apertura, seguida del contenido, seguido de la etiqueta de cierre.

+ +

Aprendizaje activo: crear tu primer elemento HTML

+ +

Edita la siguiente línea en el área Entrada envolviéndola con las etiquetas <em> y </em>. Para abrir el elemento, coloca la etiqueta de apertura <em> al principio de la línea. Para cerrar el elemento, coloca la etiqueta de cierre </em> al final de la línea. ¡Obtienes una línea en cursiva! Puedes ver tus cambios actualizados automáticamente en la caja de texto de Salida.

+ +

Si te equivocas, siempre puedes volver al código anterior mediante el botón Restablecer. Si te quedas realmente atascado, pulsa el botón Mostrar la solución para ver la solución.

+ + + +

{{ EmbedLiveSample('Código_reproducible', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Elementos anidados

+ +

Se pueden poner elementos dentro de otros elementos. Esto se llama anidamiento. Si quisiéramos decir que nuestro gato es muy gruñón, podríamos encerrar la palabra muy en un elemento {{htmlelement("strong")}} para que aparezca destacada.

+ +
<p>Mi gato es <strong>muy</strong> gruñón.</p>
+ +

Hay una forma correcta e incorrecta de anidar. En el ejemplo anterior, primero abrimos el elemento p, luego abrimos el elemento strong. Para un anidamiento adecuado, primero debemos cerrar el elemento strong, antes de cerrar el p.

+ +

El siguiente es un ejemplo de la forma incorrecta de anidar:

+ +
<p>Mi gato es <strong>muy gruñón.</p></strong>
+ +

Los elementos tienen que abrirse y cerrarse correctamente para que estén claramente dentro o fuera el uno del otro. Con el tipo de superposición en el ejemplo anterior, el navegador tiene que adivinar tu intención. Este tipo de adivinanzas puede producir resultados inesperados.

+ +

Elementos de bloque y elementos en línea

+ +

Hay dos categorías importantes de elementos en HTML — Estos son los elementos de bloque y los elementos en línea.

+ + + +

Considera el siguiente ejemplo:

+ +
<em>primero</em><em>segundo</em><em>tercero</em>
+
+<p>cuarto</p><p>quinto</p><p>sexto</p>
+
+ +

{{htmlelement("em")}} es un elemento en línea. Así, como puedes observar, los tres primeros elementos se sitúan en la misma línea, uno tras otro sin espacio entre ellos. Por otro lado, {{htmlelement("p")}} es un elemento a nivel de bloque. Cada elemento p aparece en una nueva línea, con un espacio arriba y abajo. (El espaciado se debe al {{web.link("/es/docs/Learn/CSS/Introduction_to_CSS", "estilo CSS")}} predeterminado que el navegador aplica a los párrafos).

+ +

{{ EmbedLiveSample('Elementos_de_bloque_y_elementos_en_línea', 700, 200, "", "") }}

+ +
+

Nota: HTML5 redefinió las categorías de elementos: consulta Categorías de contenido de elementos. Si bien estas definiciones son más precisas y menos ambiguas que sus predecesoras, las nuevas definiciones son mucho más complicadas de entender que block e inline . Este artículo seguirá con estos dos términos.

+
+ +
+

Nota: Los términos «en bloque» (block) y «en línea» (inline), tal como se usan en este tema, no se deberían confundir con {{web.link("/es/docs/Learn/CSS/Introduction_to_CSS/Box_model#Types_of_CSS_boxes", "los tipos de casillas de CSS")}} que se conocen con el mismo nombre. Aunque de manera predeterminada están relacionados, el hecho de cambiar el tipo de aspecto visual del CSS no cambia la categoría del elemento ni afecta a aquellos elementos que pueda contener. Una de las razones por las que HTML5 abandonó el uso de estos términos fue para evitar este tipo de confusión.

+
+ +
+

Nota: Puedes encontrar referencias útiles que incluyen listas de elementos de bloque y elementos en línea. Consulta {{web.link("/es/docs/Web/HTML/Block-level_elements", "Elementos en bloque")}} y {{web.link("/es/docs/Web/HTML/Elementos_en_línea", "Elementos en línea")}}.

+
+ +

Elementos vacíos

+ +

No todos los elementos siguen el patrón de etiqueta de apertura, contenido y etiqueta de cierre. Algunos elementos consisten solo en una etiqueta única, que se utiliza generalmente para insertar/incrustar algo en el documento en el lugar donde se le quiere incluir. Por ejemplo, el elemento {{htmlelement("img")}} inserta una imagen en la página:

+ +
<img src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png">
+ +

Este texto mostrará lo siguiente en tu página:

+ +

{{ EmbedLiveSample('Elementos_vacíos', 700, 300, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Nota: Los elementos vacíos en ocasiones también se llaman elementos nulos o vanos (void elements).

+
+ +

Atributos

+ +

Los elementos también pueden tener atributos. Los atributos tienen este aspecto:

+ +

atributo html

+ +

Los atributos contienen información extra sobre el elemento que no se mostrará en el contenido. En este caso, el atributo class asigna al elemento un identificador que se puede utilizar para dotarlo de información de estilo.

+ +

Un atributo debería tener:

+ + + +

Aprendizaje activo: Añadir atributos a un elemento

+ +

Otro ejemplo de un elemento es {{htmlelement("a")}}. Esto significa ancla. Una ancla puede convertir el texto que encierra en un hipervínculo. Las anclas pueden tener varios atributos, pero varios son como sigue:

+ + + +

Edita la línea de abajo en el área de Entrada para convertirlo en un enlace a tu sitio web favorito.

+ +
    +
  1. Añade el elemento <a>.
  2. +
  3. Añade el atributo href y el atributo title.
  4. +
  5. Especifica el atributo target para abrir el enlace en una nueva pestaña.
  6. +
+ +

Los cambios se actualizarán inmediatamente en la zona de Salida. Deberías ver un enlace que mostrará el contenido del atributo title cuando pases el ratón encima, y que te llevará a la dirección web indicada por el atributo href cuando hagas clic. Recuerda que debes incluir un espacio entre el nombre del elemento y cada atributo.

+ +

Si te equivocas, siempre puedes restablecer el código anterior pulsando el botón Restablecer. Si te quedas realmente atascado, pulsa el botón Mostrar la solución para ver la solución.

+ + + +

{{ EmbedLiveSample('Código_reproducible_2', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Atributos booleanos

+ +

En ocasiones puedes ver atributos escritos sin valor. Esto está permitido. Estos se denominan atributos booleanos. Los atributos booleanos solo pueden tener un valor, que generalmente es el mismo que el nombre del atributo. Por ejemplo, considera el atributo {{htmlattrxref("disabled", "input")}}, que puedes asignar a los elementos de entrada del formulario. (Usa esto para deshabilitar los elementos de entrada del formulario para que el usuario no pueda realizar entradas. Los elementos desactivados suelen tener una apariencia atenuada). Por ejemplo:

+ +
<input type="text" disabled="disabled">
+ +

De manera abreviada, también es posible escribirlo como se describe a continuación (además, se ha incluido un elemento de entrada de formulario no desactivado como referencia, para dar una idea más precisa de lo que sucede):

+ +
<!-- el uso del atributo deshabilitado evita que el usuario final introduzca texto en el cuadro de entrada -->
+<input type="text" disabled>
+
+<!-- se permite la entrada de texto, ya que no contiene el atributo deshabilitado -->
+<input type="text">
+
+ +

Como referencia, el ejemplo anterior también incluye un elemento de entrada de formulario no deshabilitado. El HTML del ejemplo anterior produce este resultado:

+ +

{{ EmbedLiveSample('Atributos_booleanos', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Omitir comillas en valores de atributos

+ +

Cuando observas diferentes páginas web, puedes encontrarte con todo tipo de estilos de etiquetado extraños, que incluyen valores de atributos sin comillas. Esto se permite en ciertas circunstancias, pero interrumpirá la edición en otras. Por ejemplo, si volvemos a revisar el ejemplo del enlace, sería posible escribir una versión básica con solo el atributo href, así:

+ +
<a href=https://www.mozilla.org/>mi sitio web favorito</a>
+ +

Sin embargo, las cosas no funcionarán cuando a este estilo se añada el atributo title:

+ +
<a href=https://www.mozilla.org/ title=The Mozilla homepage>mi sitio web favorito</a>
+ +

En este punto el navegador interpretará mal el cambio y pensará que el atributo title corresponde a tres atributos: un atributo title con el valor The y dos atributos booleanos: Mozilla y homepage. ¡Obviamente, esta no es la intensión! Causará errores o comportamientos inesperados, como puedes ver en el ejemplo en vivo a continuación. ¡Intenta colocar el cursor sobre el enlace para ver el texto del título!

+ +

{{ EmbedLiveSample('Omitir_comillas_en_valores_de_atributos', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Incluye siempre las comillas de atributos. Evita tales problemas y da como resultado un código más legible.

+ +

¿Comillas simples o dobles?

+ +

En este artículo todos los atributos se han incluido en comillas dobles. Sin embargo, se pueden ver comillas simples en algún código HTML. Es una cuestión de estilo. Puedes elegir libremente cuál prefieres. Ambas líneas de código son equivalentes:

+ +
<a href="http://www.ejemplo.com">Un enlace a mi ejemplo.</a>
+
+<a href='http://www.ejemplo.com'>Un enlace a mi ejemplo.</a>
+ +

Asegúrate de no mezclar ambos tipos de comillas. El siguiente ejemplo muestra un tipo de mezcla de comillas que saldrá mal:

+ +
<a href="http://www.ejemplo.com'>Un enlace a mi ejemplo.</a>
+ +

Si utilizas un tipo de comillas en tu documento HTML, puedes incluir el otro tipo de comillas para tus valores de atributo sin que esto te cause problemas:

+ +
<a href="http://www.ejemplo.com" title="¿A que es 'divertido'">Un enlace a mi ejemplo.</a>
+ +

Sin embargo, si deseas anidar unas comillas dentro de otras del mismo tipo (ya sea simples o dobles), tendrás que utilizar entidades HTML para las comillas. Por ejemplo, el siguiente código no va a funcionar:

+ +
<a href='http://www.ejemplo.com' title='¿A que es 'divertido'?'>Un enlace a mi ejemplo.</a>
+ +

Así que tendrás que hacer esto:

+ +
<a href='http://www.ejemplo.com' title='¿A que es &apos;divertido&apos;?'>Un enlace a mi ejemplo.</a>
+ +

Anatomía de un documento HTML

+ +

Los elementos HTML no son muy útiles por sí mismos. Ahora veremos cómo combinar los elementos individuales para formar una página HTML completa:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi página de prueba</title>
+  </head>
+  <body>
+    <p>Esta es mi página</p>
+  </body>
+</html>
+ +

Aquí tenemos:

+ +
    +
  1. <!DOCTYPE html>: El elemento doctype. En sus inicios, cuando el HTML llevaba poco tiempo (alrededor de 1991-1992), los doctypes servían como enlaces al conjunto de reglas que la página HTML debía seguir para que fuera considerado buen HTML. Un elemento doctype de aquella época podía parecerse a esto: + +
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    + En la actualidad se ignora y se considera un legado histórico que hay que incluir para que todo funcione correctamente. <!DOCTYPE html> es la secuencia de caracteres más corta que se acepta como elemento doctype válido. Eso es lo único que realmente necesitas saber.
  2. +
  3. <html></html>: El elemento <html>. Este elemento envuelve todo el contenido de la página. A veces se lo conoce como el elemento raíz.
  4. +
  5. <head></head>: El elemento <{{htmlelement("head")}}> (cabecera). Este elemento actúa como contenedor para todos los parámetros que quieras incluir en el documento HTML que no serán visibles a los visitantes de la página. Incluye cosas como palabras clave y la descripción de la página que quieras mostrar en los resultados de búsqueda, así como la hoja de estilo para formatear nuestro contenido, declaraciones de codificación de caracteres y más. Aprenderás más acerca de esto en el siguiente artículo de la serie.
  6. +
  7. <meta charset="utf-8">: Este elemento establece que tu documento HTML usará la codificación UTF-8, que incluye la gran mayoría de caracteres de todos los idiomas humanos escritos. En resumen: puede gestionar cualquier contenido textual que pongas en tu documento. No hay razón para no configurar este valor y te puede ayudar a evitar problemas más adelante.
  8. +
  9. <title></title>: El elemento {{htmlelement("title")}}. Este establece el título de la página, que es el título que aparece en la pestaña del navegador en la que se carga la página. El título de la página también se utiliza para describir la página cuando se marca como favorita.
  10. +
  11. <body></body>: El elemento <body>. Contiene todo el contenido que quieres mostrar a los usuarios cuando visitan tu página, ya sea texto, imágenes, vídeos, juegos, pistas de audio reproducibles o cualquier otra cosa.
  12. +
+ +

Aprendizaje activo: Añadir algunas características a un documento HTML

+ +

Si quieres escribir algo de HTML en tu ordenador local para experimentar, puedes:

+ +
    +
  1. Copiar el ejemplo de la página HTML del punto anterior.
  2. +
  3. Crear un archivo nuevo en un editor de texto.
  4. +
  5. Pegar el código en el nuevo archivo de texto.
  6. +
  7. Guardar el archivo como index.html.
  8. +
+ +
+

Nota: También puedes encontrar esta plantilla básica de HTML en el repositorio GitHub del Área MDN Learning.

+
+ +

Ahora puedes abrir este archivo en un navegador web para ver cómo se ve el código renderizado. Edita el código y actualiza el navegador para ver cuál es el resultado. En principio se verá algo así:

+ +

Una sencilla página HTML que dice esta es mi páginaEn este ejercicio, puedes editar el código en tu ordenador como se indica arriba, o puedes editarlo en la ventana editable que tienes a continuación (la ventana editable representa solo el contenido del elemento {{htmlelement("body")}}, en este caso). Intenta reproducir los siguientes pasos:

+ + + +

Si te equivocas, siempre puedes restablecer el código anterior pulsando el botón Restablecer. Si te quedas realmente atascado, pulsa el botón Mostrar la solución para ver la solución.

+ + + +

{{ EmbedLiveSample('Código_reproducible_3', 700, 600, "", "", "hide-codepen-jsfiddle") }}

+ +

Los espacios en blanco en HTML

+ +

En los ejemplos anteriores se han incluido espacios en blanco y saltos de línea en el código. Esto realmente no es necesario. Los dos siguientes fragmentos de código son equivalentes:

+ +
<p>Los perros son tontos.</p>
+
+<p>Los    perros        son
+         tontos.</p>
+ +

No importa cuántos espacios en blanco se utilicen (incluye tanto caracteres de espacio como saltos de línea) el intérprete de HTML reduce cada secuencia de espacio en blanco a un único espacio al interpretar el código. Entonces, ¿por qué utilizar espacios en blanco? La respuesta está en la legibilidad.
+
+ Es más fácil comprender lo que está sucediendo en tu código si lo tienes bien formateado. En nuestro HTML cada elemento anidado está sangrado dos espacios más con respecto al exterior. Depende de ti qué estilo de formato utilizas (cuántos espacios para cada nivel de sangría, por ejemplo) pero debes plantearte el uso de algún tipo de formato.

+ +

Referencias a entidades: Inclusión de caracteres especiales en HTML

+ +

En HTML, los caracteres <, >,",' y & son caracteres especiales. Forman parte de la sintaxis HTML. Entonces, ¿cómo incluye uno de estos caracteres especiales en tu texto? Por ejemplo, si deseas utilizar un signo comercial o menor que, y no hacer que se interprete como código.

+ +

Haces esto con referencias de caracteres. Estos son códigos especiales que representan caracteres, para ser usados en estas circunstancias exactas. Cada referencia de caracter comienza con un signo de ampersand (&) y finaliza con un punto y coma (;).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Caracter literalEquivalente de referencia de caracteres
<&lt;
>&gt;
"&quot;
'&apos;
&&amp;
+ +

El equivalente de referencia de caracter podría recordarse fácilmente porque el texto que utiliza se puede ver como menor que para '&lt;' , cita para ' &quot; ' y de manera similar para otros. Para obtener más información sobre la referencia de entidad, consulta {{interwiki("wikipedia", "Anexo:Referencias a entidades de caracteres XML y HTML")}} en (Wikipedia).
+
+ Considera los dos siguientes párrafos:

+ +
<p>En HTML, defines un párrafo con el elemento <p>.</p>
+
+<p>En HTML, defines un párrafo con el elemento &lt;p&gt;.</p>
+ +

En la salida en vivo de abajo, puedes ver que el primer párrafo salió mal. El navegador interpreta la segunda instancia de <p> como el inicio de un nuevo párrafo. El segundo párrafo se ve bien porque hemos remplazado < y > por sus referencias correspondientes.

+ +

{{ EmbedLiveSample('Referencias_a_entidades_Inclusión_de_caracteres_especiales_en_HTML', 700, 200) }}

+ +
+

Nota: En la Wikipedia se puede localizar un listado de todas las referencias de entidades de caracteres HTML disponibles: {{interwiki("wikipedia", "Anexo:Referencias a entidades de caracteres XML y HTML")}}. Observa que no necesitas usar ninguna referencia de entidad más para ningún otro de estos símbolos porque los navegadores modernos gestionan estos símbolos correctamente siempre y cuando en tu HTML hayas {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "establecido la codificación de el juego de caracteres universal UTF-8", "#Specifying_your_document's_character_encoding")}}.

+
+ +

Comentarios HTML

+ +

En HTML hay un mecanismo para escribir comentarios en el código. Los comentarios son ignorados por el navegador y, por tanto, son invisibles para el usuario. El propósito de los comentarios es permitirte incluir notas en el código para explicar tu lógica o codificación. Esto es muy útil si regresas a un código base después de estar ausente el tiempo suficiente como para no recordarlo por completo. Del mismo modo, los comentarios son invaluables ya que diferentes personas están realizando cambios y actualizaciones.

+ +

Para convertir en un comentario una sección de contenido de tu archivo HTML, debes delimitarlo con los marcadores especiales <!-- y -->. Por ejemplo:

+ +
<p>No soy un comentario</p>
+
+<!-- <p>¡Yo sí!</p> -->
+ +

Como puedes ver a continuación, el primer párrafo aparece, pero el segundo no.

+ +

{{ EmbedLiveSample('Comentarios_HTML', 700, 100, "", "", "hide-codepen-jsfiddle") }}

+ +

Resumen

+ +

Has llegado al final del artículo. Espero que hayas disfrutado del recorrido los conceptos básicos del HTML.
+ En este punto ya deberías entender el lenguaje, cómo funciona en un nivel básico y deberías poder escribir algunos elementos y atributos. También deberías poder escribir algunos elementos y atributos. Los artículos posteriores de este módulo profundizan en algunos de los temas aquí presentados, además de presentar otros conceptos del lenguaje.

+ +
+

Nota: En este punto, a medida que empieces a aprender más sobre HTML, es posible que también desees comenzar a explorar los conceptos básicos de las Hojas de estilo en cascada (Cascading style sheets) o {{web.link("/es/docs/Learn/CSS", "CSS")}}. CSS, es el lenguaje utilizado para estilizar páginas web. (por ejemplo, cambiar fuentes o colores, o alterar el diseño de la página) HTML y CSS funcionan bien juntos, como pronto descubrirás.

+
+ +

Ve también

+ + + +
{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML")}}
+ +
+ +

En este módulo

+ + diff --git a/files/es/learn/html/introduccion_a_html/marking_up_a_letter/index.html b/files/es/learn/html/introduccion_a_html/marking_up_a_letter/index.html new file mode 100644 index 0000000000..e53bb01826 --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/marking_up_a_letter/index.html @@ -0,0 +1,88 @@ +--- +title: Marcando una Carta +slug: Learn/HTML/Introduccion_a_HTML/Marking_up_a_letter +tags: + - Cabecera + - Codificación + - Enlaces + - Evaluación + - Principiante + - Texto +translation_of: Learn/HTML/Introduction_to_HTML/Marking_up_a_letter +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}
+ +

Todos aprendemos a escribir una carta más tarde o más temprano; es también práctico practicar con nuestras habilidades para dar forma a los textos. En esta prueba deberás demostrar tus habilidades para dar forma a textos, incluyendo enlaces, además pondremos a prueba tu familiaridad con algunos contenidos de encabezamiento <head> en HTML.

+ + + + + + + + + + + + +
Prerrequisitos:Antes de intentar este examen deberías haber trabajado los artículos Getting started with HTML, What's in the head? Metadata in HTML, HTML text fundamentals, Creating hyperlinks, y Advanced text formatting.
Objetivos:Probar las habilidades básicas y avanzadas de formateo de texto e hyperlinks, y el conocimiento de los encabezamientos en HTML.
+ +

Punto de partida

+ +

Para comenzar esta prueba, deberemos copiar el texto que deberemos trabajar, y el CSS que necesitaremos incluir en nuestro HTML. Crearemos un archivo nuevo .html usando nuestro editor de texto (o alternativamente usaremos otros como JSBin o Thimble para hacer nuestra prueba).

+ +

Resumen del proyecto a desarrollar

+ +

En este proyecto tu tarea será publicar una carta que debe estar alojada en la intranet de una universidad. La carta es la respuesta de un compañero investigador a un posible estudiante de postgrado en relación a su deseo de trabajar en la universidad.

+ +

Semánticas de bloque/estructurales:

+ + + +

Semánticas intralínea:

+ + + +

El encabezamiento del documento:

+ + + +

Pistas y recomendaciones

+ + + +

Example

+ +

The following screenshot shows an example of what the letter might look like after being marked up.

+ +

+ +

Evaluación

+ +

Si estás haciendo esta prueba como parte de un curso organizado, deberías entregar tu trabajo al profesor para que lo corrija. Si estás auto-aprendiendo puedes conseguir la guía de corrección fácilmente pidiendola en el Hilo del area de aprendizaje, o en el canal IRC de #mdn en Mozilla IRC. Intenta hacerlo primero — no ganarás nada haciendo trampas.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Debugging_HTML", "Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content", "Learn/HTML/Introduction_to_HTML")}}

diff --git a/files/es/learn/html/introduccion_a_html/metados_en/index.html b/files/es/learn/html/introduccion_a_html/metados_en/index.html new file mode 100644 index 0000000000..6fc5f94ab0 --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/metados_en/index.html @@ -0,0 +1,299 @@ +--- +title: ¿Qué hay en la cabecera? Metadatos en HTML +slug: Learn/HTML/Introduccion_a_HTML/Metados_en +tags: + - Cabecera + - CodingScripting + - Guía + - HTML + - Meta + - Metadatos + - Novato + - Principiante + - favicon + - head + - lang + - metadata +translation_of: Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}
+ +

El elemento {{Glossary("Head", "head")}} de un documento HTML es la parte que no se muestra en el navegador cuando se carga la página. Contiene información como el título ({{htmlelement("title")}}) de la página, enlaces al {{Glossary("CSS")}} (si quieres aplicar estilo a tu contenido HTML con CSS), enlaces para personalizar favicon, y otros metadatos (datos sobre el HTML, como quién lo escribió y palabras claves importantes que describen el documento). En este artículo abarcaremos todo esto y más, para darte bases sólidas en el manejo del marcado y otro código que debería estar presente en tu cabecera.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con el HTML básico, que se expone en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started", "Empezar con el HTML")}}.
Objetivo:Aprender acerca de la cabecera HTML {{Glossary("Head", "head")}}, cuál es su propósito, los elementos más importantes que puede contener, y qué efecto puede tener sobre el documento HTML.
+ +

¿Qué hay en la cabecera HTML?

+ +

Vamos a revisar el {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started#Anatomy_of_an_HTML_document", "documento HTML que se revisó en el artículo anterior")}}:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Mi página de prueba</title>
+  </head>
+  <body>
+    <p>Esta es mi página</p>
+  </body>
+</html>
+ +

La cabecera HTML es el contenido del elemento {{htmlelement("head")}} — a diferencia del contenido del elemento {{htmlelement("body")}} (que sí se muestra en la página cuando se carga en el navegador), el contenido de la cabecera no se muestra en la página. Por el contrario, la función de la cabecera es contener los {{Glossary("Metadata", "metadatos")}} del documento. En el ejemplo anterior, la cabecera es bastante reducida:

+ +
<head>
+  <meta charset="utf-8">
+  <title>Mi página de prueba</title>
+</head> 
+ +

En páginas más grandes, sin embargo, la cabecera puede llegar a contener bastantes elementos. Prueba a ir a algunos de tus sitios web favoritos y comprueba el contenido de la cabecera usando las {{web.link("/es/docs/Learn/Common_questions/What_are_browser_developer_tools", "herramientas para el desarrollador")}}. Nuestro objetivo aquí no es mostrarte cómo usar todo lo que puedes incluir en la cabecera, sino enseñarte cómo usar los elementos principales que vas a incluir en la cabecera y que te familiarices con ellos. Empecemos.

+ +

Añadir un título

+ +

Ya hemos visto el elemento {{htmlelement("title")}} en acción — se puede usar para poner un título al documento. Sin embargo, esto se puede confundir con el elemento {{htmlelement("h1")}}, que se utiliza para poner un encabezado de nivel superior al cuerpo de tu contenido — esto también se conoce como el título de la página. ¡Pero son cosas diferentes!

+ + + +

Aprendizaje activo: Análisis de un ejemplo sencillo

+ +
    +
  1. Para comenzar este aprendizaje activo, te proponemos ir a nuestro repositorio de GitHub y descargues una copia de nuestra página title-example.html. Lo puedes hacer de las siguientes maneras: + +
      +
    1. Copia y pega el código de la página en un archivo de texto nuevo en tu editor de código, luego guárdalo en un lugar conveniente.
    2. +
    3. Presiona el botón "Raw" en la página de GitHub, lo cual hace que aparezca el código sin procesar (posiblemente en una nueva pestaña del navegador). A continuación, en el menú de tu navegador elige Archivo → Guardar página como... y selecciona un lugar adecuado para guardar el archivo.
    4. +
    +
  2. +
  3. Ahora abre el archivo en tu navegador. Deberías ver algo como esto: +

    Una sencilla página web con el título configurado a <title> element, y el <h1> configurado a <h1> element.Ahora debería quedar claro dónde aparece el contenido de <h1> y dónde aparece el contenido de <title>.

    +
  4. +
  5. También podrías probar a abrir el código en tu editor de código, editar el contenido de estos elementos y luego actualizar la página en tu navegador. Juega un poco con ello.
  6. +
+ +

El contenido del elemento <title> también se usa de otras formas. Por ejemplo, si intentas marcar la página como favorita (Marcadores → Marcar esta página, o el icono en forma de estrella de Firefox), verás que el nombre que se sugiere para el marcado es el contenido del elemento <title>.

+ +

Se está marcando una página web en Firefox; el nombre del marcador se ha completado automáticamente con el contenido del elemento <title>

+ +

El contenido de <title> también se usa en el resultado de las búsquedas, como verás a continuación.

+ +

Metadatos: el elemento <meta>

+ +

Los metadatos son datos que describen datos, y HTML tiene una forma «oficial» de introducir metadatos en un documento — el elemento {{htmlelement("meta")}}. Por supuesto, el resto de los elementos de los que hablaremos en este artículo también se podrían considerar metadatos. Hay muchos diferentes tipos de elementos <meta> que se pueden incluir en el <head> de tu página, pero no vamos a intentar explicarlos todos en esta etapa porque resultaría demasiado confuso. En lugar de ello vamos a explicar algunas cuestiones con las que seguramente te vas a encontrar, solo para que te hagas una idea.

+ +

La codificación de caracteres de tu documento

+ +

El ejemplo que vimos arriba incluía esta línea:

+ +
<meta charset="utf-8">
+ +

Este elemento simplemente especifica la codificación de caracteres del documento — es decir, el conjunto de caracteres que el documento puede usar. utf-8 es un conjunto de caracteres universal que incluye casi todos los caracteres de casi cualquier idioma humano. Esto significa que tu página web podrá gestionar la visualización de cualquier idioma; por lo tanto, resulta una buena idea configurarlo en cada página web que crees. Por ejemplo, tu página podría gestionar inglés y japonés sin problemas:

+ +

Una página web que contiene caracteres en inglés y japonés, con la codificación de caracteres establecida en universal o utf-8. Ambos idiomas se muestran bien.Si configuras tu codificación de caracteres en ISO-8859-1, por ejemplo (el juego de caracteres para el alfabeto latino), la representación de tu página puede aparecer desordenada:

+ +

una página web que contiene caracteres en inglés y japonés, con la codificación de caracteres configurada en latín. Los caracteres japoneses no se muestran correctamente

+ +
+

Nota: Algunos navegadores (Chrome, por ejemplo) automáticamente arreglan la codificación de caracteres incorrecta, de modo que según el navegador que uses, puede que no te topes con este problema. Aun así, deberías incluir una codificación de caracteres utf-8 en tu página web para evitar que se presenten potenciales problemas con otros navegadores.

+
+ +

Aprendizaje activo: Experimenta con la codificación de caracteres

+ +

Para probar esto, vuelve a visitar la plantilla HTML simple que obtuviste en la sección anterior sobre <title> (la página title-example.html) e intenta cambiar el valor de la propiedad meta charset por ISO-8859-1 y añade el japonés a tu página. Este es el código que usamos:

+ +
<p>Ejemplo en japonés: ご飯が熱い。</p>
+ +

Añadir un autor y descripción

+ +

Muchos elementos <meta> incluyen atributos name y content:

+ + + +

Dos de esos metadatos que resultan útiles de incluir en tu página definen al autor de la página y proporcionan una descripción concisa de la página. Veamos un ejemplo:

+ +
<meta name="author" content="Chris Mills">
+<meta name="description" content="El área de aprendizaje de MDN pretende
+proporcionar a los recién llegados a la web todo lo que deben
+saber para empezar a desarrollar páginas web y aplicaciones web.">
+ +

Especificar un autor resulta ventajoso por diversos motivos: es útil saber quién escribió la página para poder ponerte en contacto con el autor si tienes preguntas sobre el contenido. Algunos sistemas de gestión de contenido tienen herramientas para extraer automáticamente la información del autor de la página y ponerla a disposición para tales fines.

+ +

Especificar una descripción que incluya palabras clave relacionadas con el contenido de tu página resulta útil porque tiene el potencial de hacer que la página aparezca más arriba en las búsquedas relevantes que efectúan los motores de búsqueda (tales actividades se denominan optimizaciones del motor de búsqueda ({{web.link("/es/docs/Glossary/SEO", "Optimización de motores de búsqueda")}}) o {{Glossary("SEO")}}.)

+ +

Aprendizaje activo: El uso de la descripción en los motores de búsqueda

+ +

La descripción también se usa en las páginas de resultados del motor de búsqueda. Repasemos un ejercicio para explorar esto:

+ +
    +
  1. Ve a la página de inicio de Mozilla Developer Network.
  2. +
  3. Observa el código fuente de la página (Ctrl+clic o clic con el botón derecho en la página y selecciona la opción del menú Ver código fuente de la página).
  4. +
  5. Encuentra la etiqueta del metadato description. Se verá más o menos así (aunque puede cambiar con el tiempo): +
    <meta name="description" content="The Mozilla Developer
    +  Network (MDN) proporciona información sobre tecnologías
    +  de código abierto que incluyen HTML, CSS y APIs tanto para sitios web como para aplicaciones HTML5.
    +  También documenta productos Mozilla como el sistema operativo Firefox.">
    +
  6. +
  7. Ahora busca "Mozilla Developer Network" en tu motor de búsqueda favorito (nosotros hemos utilizado Google). Observarás que efectivamente merece la pena que tener el contenido de la descripción <meta> y el elemento <title> que se utiliza en la búsqueda. +

    Resultado de búsqueda en Yahoo para "Mozilla Developer Network"

    +
  8. +
+ +
+

Nota: En Google verás algunas subpáginas relevantes de MDN enumeradas debajo del enlace principal a la página principal de MDN (se trata de los llamados sitelinks y se pueden configurar con las Herramientas de administrador de Google), una forma de mejorar los resultados para tu sitio con el motor de búsqueda de Google.

+
+ +
+

Nota: Muchas características <meta> ya no se usan. Por ejemplo, los motores de búsqueda ignoran el elemento <meta> (<meta name="keywords" content="pon, tus, palabras clave, aquí">), que se supone que facilita palabras clave para motores de búsqueda de forma que se determine la relevancia de esa página según diferentes términos de búsqueda, porque los spammers rellenaban la lista de palabras clave con cientos de palabras clave que sesgaban los resultados.

+
+ +

Otros tipos de metadatos

+ +

Al navegar por la web también puedes encontrar otros tipos de metadatos. Muchas de las funciones que verás en los sitios web son creaciones propietarias diseñadas para proporcionar a ciertos sitios (como los sitios de redes sociales) información específica que puedan usar.

+ +

Por ejemplo, Open Graph Data es un protocolo de metadatos que Facebook inventó para proveer metadatos más ricos para los sitios web. En las fuentes de código de MDN, encontrarás esto:

+ +
<meta property="og:image" content="https://developer.cdn.mozilla.net/static/img/opengraph-logo.dc4e08e2f6af.png">
+<meta property="og:description" content="The Mozilla Developer Network (MDN) proporciona información
+sobre tecnologías Open Web, incluidas HTML, CSS y APIs para ambos sitios web
+y aplicaciones HTML5. También documenta productos Mozilla, como el sistema operativo Firefox.">
+<meta property="og:title" content="Mozilla Developer Network">
+ +

Un efecto de esto es que cuando desde Facebook enlazas a un MDN, el enlace aparece con una imagen y una descripción, lo que resulta en una experiencia más enriquecedora para los usuarios.

+ +

Datos abiertos del protocolo de gráficos de la página de inicio de MDN como se muestra en Facebook, mostrando una imagen, título y descripción.

+ +

Twitter también tiene sus metadatos propios, las Twitter Cards, que tienen un efecto similar cuando la URL del sitio se muestra en twitter.com. Por ejemplo:

+ +
<meta name="twitter:title" content="Mozilla Developer Network">
+ +

Agregar iconos personalizados a tu sitio

+ +

Para enriquecer un poco más el diseño de tu sitio puedes añadir en tus metadatos referencias a iconos personalizados, que se mostrarán en determinados contextos. El más común de ellos es el favicon (abreviatura de favorite iconicono «favorito», referido al uso que se le da en las listas de «favoritos» o de marcadores («bookmarks»).

+ +

El humilde favicon ha existido durante muchos años. Es el primer icono de este tipo: un icono cuadrado de 16 píxeles que se utiliza en varios lugares. Es posible que veas (según el navegador) favicons que se muestran en la pestaña del navegador que contiene cada página abierta y junto a las páginas marcadas en el panel de marcadores.

+ +

Para añadir un favicon a tu página:

+ +
    +
  1. Guárdalo en el mismo directorio que la página index de tu sitio, en formato .ico (la mayoría de los buscadores admiten favicon en los formatos más comunes como .gif o .png, pero usar el formato ICO garantiza que funcionará hasta en Internet Explorer 6.)
  2. +
  3. Añade la siguiente línea de referencia en el {{HTMLElement("head")}} de tu HTML: +
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    +
  4. +
+ +

Los navegadores modernos usan favicons en diversos lugares, como en la etiqueta de la página que está abierta y en el panel de favoritos cuando la añades a tu lista de páginas favoritas:

+ +

El panel de marcadores de Firefox, que muestra un ejemplo marcado con un favicon junto a él.

+ +

Hoy día hay un montón de otros tipos de iconos a tener presentes. Por ejemplo, los encontrarás en el código fuente de la página de inicio de MDN:

+ +
<!-- iPad de tercera generación con pantalla de alta resolución: -->
+<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://developer.cdn.mozilla.net/static/img/favicon144.a6e4162070f4.png">
+<!-- iPhone con pantalla de alta resolución: -->
+<link rel="apple-touch-icon-precomposed" sizes="114x114" href="https://developer.cdn.mozilla.net/static/img/favicon114.0e9fabd44f85.png">
+<!-- iPad de primera y segunda generación: -->
+<link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://developer.cdn.mozilla.net/static/img/favicon72.8ff9d87c82a0.png">
+<!-- Dispositivos iPhone sin pantalla Retina, iPod Touch y Android 2.1+: -->
+<link rel="apple-touch-icon-precomposed" href="https://developer.cdn.mozilla.net/static/img/favicon57.a2490b9a2d76.png">
+<!-- favicon básico -->
+<link rel="shortcut icon" href="https://developer.cdn.mozilla.net/static/img/favicon32.e02854fdcf73.png">
+ +

Los comentarios explican para qué se usa cada icono (estos elementos abarcan situaciones como aportar un buen icono de alta resolución para usarlo cuando la página web se guarda en la página de inicio de un iPad).

+ +

No te preocupes demasiado sobre la implementación de todos estos tipos de iconos por el momento; se trata de una característica bastante avanzada y no se espera que tengas conocimientos de ello para avanzar en el curso. El propósito principal aquí es darte a conocer estos elementos por si te los encuentras mientras examinas el código fuente de otros sitios web.

+ +
+

Nota: Si tu sitio web utiliza una política de seguridad de contenido (content security policy o CSP) para mejorar la seguridad, la política afecta al favicon. Si te encuentras con problemas como que el favicon no se carga, comprueba que la respuesta a {{HTTPHeader("Content-Security-Policy")}} del header Content-Security-Policy para la directriz img-src en la cabecera no impide el acceso a este.

+
+ +

Aplicar CSS y JavaScript a HTML

+ +

Prácticamente todos los sitios web usan {{Glossary("CSS")}} para darles un buen aspecto y {{Glossary("JavaScript")}} para añadir funcionalidades interactivas, como reproductores de vídeo, mapas, juegos y demás. La manera más habitual de añadir CSS y JavaScript a una página web es con los elementos <link> y el elemento <script>, respectivamente.

+ + + +

Aprendizaje activo: aplicar CSS y JavaScript a una página

+ +
    +
  1. Para iniciar este aprendizaje activo, haz una copia de nuestros archivos meta-example.html, script.js y style.css, y guárdalos en un mismo directorio de tu ordenador. Asegúrate de que se guardan con los nombres y extensiones correctas.
  2. +
  3. Abre el archivo HTML tanto en tu navegador como en tu editor de texto.
  4. +
  5. Sigue la información facilitada anteriormente y añade los elementos <link> y <script> a tu HTML para aplicarle CSS y JavaScript.
  6. +
+ +

Si lo has hecho correctamente, al guardar tu HTML y actualizar tu navegador, deberías poder ver que las cosas han cambiado:

+ +

Ejemplo que muestra una página con CSS y JavaScript aplicados. El CSS ha hecho que la página se vuelva verde, mientras que JavaScript ha agregado una lista dinámica a la página

+ + + +
+

Nota: Si te encallas en este ejercicio y no logras ejecutar los archivos CSS/JS, comprueba tu página de ejemplo css-and-js.html.

+
+ +

Establecer el idioma principal del documento

+ +

Por último, merece la pena mencionar que puedes (y realmente deberías) especificar el idioma de tu página. Esto se puede hacer añadiendo el atributo {{web.link("/es/docs/Web/HTML/Global_attributes/lang", "lang")}} a la etiqueta de apertura del HTML (como se ve en el meta-example.html y se muestra abajo).

+ +
<html lang="es-MX">
+ +

Esto resulta útil en muchos sentidos. Los motores de búsqueda indizarán tu documento HTML de modo más efectivo si estableces el idioma (permitiendo, por ejemplo, que aparezca correctamente en los resultados del idioma especificado), y resulta útil para que las personas con discapacidad visual que utilizan los lectores de pantalla (por ejemplo, la palabra «six» existe tanto en francés como en inglés, pero su pronunciación es diferente).

+ +

También puedes establecer que las subsecciones de tu documento se reconozcan en diferentes idiomas. Por ejemplo, podemos establecer que nuestra sección de japonés se reconozca como japonés, de la siguiente manera:

+ +
<p>Ejemplo Japonés: <span lang="ja">ご飯が熱い。</span>.</p>
+ +

El estándar {{interwiki("wikipedia", "ISO_639-1")}} define estos códigos. Puedes encontrar más información sobre ello en Etiquetas de idioma en HTML y XML.

+ +

Resumen

+ +

Esto marca el final de nuestra guía rápida del {{Glossary("head")}} de HTML — aún hay muchas más cosas que puedes hacer aquí, pero una guía exhaustiva puede ser aburrida y confusa a estas alturas, ¡y nosotros queremos darte una idea de las cuestiones más comunes con las que te encontrarás aquí por ahora! En el siguiente artículo veremos los fundamentos de texto de HTML.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/Getting_started", "Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals", "Learn/HTML/Introduction_to_HTML")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__enlaces/index.html b/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__enlaces/index.html new file mode 100644 index 0000000000..0e8dc1bfaf --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__enlaces/index.html @@ -0,0 +1,99 @@ +--- +title: 'Prueba tus habilidades: Enlaces' +slug: 'Learn/HTML/Introduccion_a_HTML/Prueba_tus_habilidades:_Enlaces' +translation_of: 'Learn/HTML/Introduction_to_HTML/Test_your_skills:_Links' +--- +
{{learnsidebar}}
+ +

El objetivo de esta pueba de habilidad es evaluar si has comprendido nuestro artículo Creando hipervínculos.

+ +
+

Nota: Puedes intentar resolver esta prueba en los editores interactivos más abajo, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePen, jsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te atascas, pide ayuda — mira la sección {{anch("Evaluación o ayuda adicional")}} al final de esta página.

+
+ +

Enlaces 1

+ +

En esta tarea necesitamos tu ayuda para completar los enlaces en nuestra página de información sobre Ballenas:

+ + + +
+

Nota: El primer enlace en el ejemplo tiene el atributo target="_blank" , así que cuando haces click en él, abre la página en una pestaña nueva. Esto no es estrictamente una buena práctica, pero lo hemos hecho aquí para que la página no se abra en el <iframe> incrustado, ¡eliminando el código de ejemplo en el proceso!

+
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/links/links1.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Enlaces 2

+ +

En esta tarea queremos que completes los cuatro enlaces para que se dirijan al lugar apropiado:

+ + + +
+

Nota: Los primeros tres enlaces en el ejemplo tienen el atributo target="_blank" especificado en ellos, abren la página enlazada en una nueva pestaña del navegador. Esto no es estrictamente una buena práctica, pero hemos hecho esto aquí para que las páginas no se abran dentro del <iframe> incrustado, ¡eliminando el código de ejemplo en el proceso!

+
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/links/links2.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Enlaces 3

+ +

Los siguientes enlaces dirigen a una página informativa acerca de los Narvales, una dirección de correo electrónico de soporte, y un documento PDF cuyo tamaño es 4MB. En esta tarea queremos que:

+ + + +
+

Nota: Los primeros tres enlaces en el ejemplo tienen el atributo target="_blank" especificado en ellos, abren la página enlazada en una nueva pestaña del navegador. Esto no es estrictamente una buena práctica, pero hemos hecho esto aquí para que las páginas no se abran dentro del <iframe> incrustado, ¡eliminando el código de ejemplo en el proceso!

+
+ +

Intenta actualizar el código en vivo más abajo para mostrar el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/links/links3.html", '100%', 700)}}

+ +
+

Descarga el inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos que se encuentran más arriba.

+ +

Si deseas que tu trabajo sea evaluado, o estás atorado y quieres solicitar ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea con capacidad de compartir como CodePenjsFiddle, o Glitch. Puedes escribir el código por ti mismo, o usar los archivos de punto de inicio enlazados en las secciones superiores.
  2. +
  3. Escribe una publicación solicitando evaluacion y/o ayuda en el MDN Discourse forum Learning category. Tu publicación debería incluir: +
      +
    • Un título descriptivo como "Solicito evaluacion para la prueba de habilidad de texto básico HTML 1".
    • +
    • Detalles de lo que ya has intentado, y que te gustaría que hiciéramos, por ejemplo, si estas atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que quieres que sea evaluado o por el que necesitas ayuda en un  editor en linea con capacidad de compartir (como se mencionó en el paso 1 más arriba). Esta es una buena práctica  - Es muy dificil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la tarea o página de evaluacion actual, para que podamos encontrar la pregunta con la cual necesitas ayuda.
    • +
    +
  4. +
diff --git "a/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__texto_b\303\241sico_html/index.html" "b/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__texto_b\303\241sico_html/index.html" new file mode 100644 index 0000000000..f35a083987 --- /dev/null +++ "b/files/es/learn/html/introduccion_a_html/prueba_tus_habilidades_colon__texto_b\303\241sico_html/index.html" @@ -0,0 +1,72 @@ +--- +title: 'Prueba tus habilidades: Texto básico HTML' +slug: 'Learn/HTML/Introduccion_a_HTML/Prueba_tus_habilidades:_Texto_básico_HTML' +tags: + - Aprendizaje + - HTML + - Principiante + - Prueba tus habilidades + - Texto +translation_of: 'Learn/HTML/Introduction_to_HTML/Test_your_skills:_HTML_text_basics' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba de habilidad es evaluar si has comprendido el artículo Fundamentos de texto en HTML.

+ +
+

Nota: Puedes intentar resolverlo en los editores interactivos de más abajo, sin embargo puede ser muy úytil descargar el código y usar una herramienta en línea como CodePen, jsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te atascas, entonces pídenos ayuda — busca en la sección {{anch("Assessment or further help")}} al final de esta página.

+
+ +

Texto básico HTML 1

+ +

En esta tarea queremos que etiquetes el HTML entregado utilizando elementos semánticos de encabezado y párrafo. Intenta actualizando el código más abajo para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/basic-text/basic-text1.html", '100%', 700)}}

+ +
+

Descarga el punto de inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Texto básico HTML 2

+ +

En esta tarea necesitamos que cambies la primera lista no marcada en una lista no ordenada, y la segunda en una lista ordenada.

+ +

Intenta actualizando el código más abajo para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/basic-text/basic-text2.html", '100%', 700)}}

+ +
+

Descarga el punto de inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Texto básico HTML 3

+ +

En esta tarea se te entrega un párrafo, y tu objetivo es usar algunos elementos en línea para marcar algunas palabras con importancia, y otras con énfasis

+ +

Intenta actualizando el código más abajo para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/basic-text/basic-text3.html", '100%', 700)}}

+ +
+

Descarga el punto de inicio de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos que se encuentran más arriba.

+ +

Si deseas que tu trabajo sea evaluado, o estás atorado y quieres solicitar ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea con capacidad de compartir como CodePen, jsFiddle, o Glitch. Puedes escribir el código por ti mismo, o usar los archivos de punto de inicio enlazados en las secciones superiores.
  2. +
  3. Escribe una publicación solicitando evaluacion y/o ayuda en el MDN Discourse forum Learning category. Tu publicación debería incluir: +
      +
    • Un título descriptivo como "Solicito evaluacion para la prueba de habilidad de texto básico HTML 1".
    • +
    • Detalles de lo que ya has intentado, y que te gustaría que hiciéramos, por ejemplo, si estas atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que quieres que sea evaluado o por el que necesitas ayuda en un  editor en linea con capacidad de compartir (como se mencionó en el paso 1 más arriba). Esta es una buena práctica  - Es muy dificil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la tarea o página de evaluacion actual, para que podamos encontrar la pregunta con la cual necesitas ayuda.
    • +
    +
  4. +
diff --git a/files/es/learn/html/introduccion_a_html/test_your_skills_colon__advanced_html_text/index.html b/files/es/learn/html/introduccion_a_html/test_your_skills_colon__advanced_html_text/index.html new file mode 100644 index 0000000000..f29638eb81 --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/test_your_skills_colon__advanced_html_text/index.html @@ -0,0 +1,67 @@ +--- +title: 'Pon a prueba tus habilidades: texto HTML avanzado' +slug: 'Learn/HTML/Introduccion_a_HTML/Test_your_skills:_Advanced_HTML_text' +translation_of: 'Learn/HTML/Introduction_to_HTML/Test_your_skills:_Advanced_HTML_text' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba de habilidad es evaluar si ha entendido nuestras   formato de texto avanzado articulo.

+ +
+

NOTA:Puede probar soluciones en los editores interactivos a continuación; sin embargo, puede resultar útil descargar el código y utilizar una herramienta en línea como  CodePen, jsFiddle, o Glitch trabajar en las tareas.
+
+ Si se atasca, pídanos ayuda; consulte la {{anch("Assessment or further help")}} section at the bottom of this page.

+
+ +

Texto HTML avanzado 1

+ +

En esta tarea, queremos que convierta los animales proporcionados y sus definiciones en una lista de descripción.
+
+ Intente actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/advanced-text/advanced-text1.html", '100%', 700)}}

+ +
+

Descarga el puno de partida para esta tarea to work in your own editor or in an online editor.

+
+ +

Texto HTML avanzado 2

+ +

En esta tarea, queremos que agregue algo de semántica al HTML proporcionado de la siguiente manera:

+ + + +

Intente actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/html/introduction-to-html/tasks/advanced-text/advanced-text2.html", '100%', 700)}}

+ +
+

Descarga el punto de partida para esta tarea para trabajar en su propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +
+
Puede practicar estos ejemplos en los editores interactivos anteriores.
+
+Si desea que se evalúe su trabajo, o está atascado y desea pedir ayuda:
+ +
+
+ +
    +
  1. Pon tu trabajo en un editor que se pueda compartir en línea, como  CodePen, jsFiddle, o Glitch. Puede escribir el código usted mismo o utilizar los archivos de punto de inicio vinculados en las secciones anteriores.
  2. +
  3. Escriba una publicación solicitando evaluación y / o ayuda en el  MDN Discourse forum Learning category. Tu publicación debe incluir: +
      +
    • Un título descriptivo como "Se busca evaluación para la prueba de habilidad de texto avanzado HTML 1".
    • +
    • Detalles de lo que ya ha probado y lo que le gustaría que hiciéramos, p. Ej. si está atascado y necesita ayuda, o quiere una evaluación.
    • +
    • Un enlace al ejemplo que desea evaluar o con el que necesita ayuda, en un editor que se puede compartir en línea (como se mencionó en el paso 1 anterior). Esta es una buena práctica para entrar: es muy difícil ayudar a alguien con un problema de codificación si no puede ver su código.
    • +
    • Un enlace a la página de la tarea o evaluación real, para que podamos encontrar la pregunta con la que desea ayuda.
    • +
    +
  4. +
diff --git a/files/es/learn/html/introduccion_a_html/texto/index.html b/files/es/learn/html/introduccion_a_html/texto/index.html new file mode 100644 index 0000000000..912acb7dfe --- /dev/null +++ b/files/es/learn/html/introduccion_a_html/texto/index.html @@ -0,0 +1,970 @@ +--- +title: Fundamentos de texto en HTML +slug: Learn/HTML/Introduccion_a_HTML/texto +tags: + - CodingScripting + - Encabezados + - Estructuras + - Guía + - HTML + - Introducción a HTML + - Novato + - Principiante + - Párrafos + - Texto + - aprende + - semántica +translation_of: Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}
+ +

Una de las principales funciones de HTML es dar al texto estructura y significado (también conocido como {{Glossary("semantics", "semántica")}}), de forma que un navegador pueda mostrarlo correctamente. Este articulo explica la forma en que se puede usar {{Glossary("HTML")}} para estructurar una página de texto añadiendo encabezados y párrafos, enfatizando palabras, creando listas y más.

+ + + + + + + + + + + + +
Prerrequisitos:Estar familiarizado con el HTML básico, que se expone en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Getting_started", "Empezar con HTML")}}.
Objetivo:Aprender a marcar una página de texto básica para darle estructura y significado, incluidos párrafos, encabezados, listas, efectos de énfasis y citas.
+ +

Conceptos básicos: Encabezados y párrafos

+ +

La mayor parte del texto estructurado está compuesto por encabezados y párrafos, independientemente de si lees una historia, un periódico, un libro de texto, una revista, etc.

+ +

Un ejemplo de la portada de un periódico, que muestra el uso de un encabezado, subtítulos y párrafos de nivel superior.

+ +

El contenido estructurado simplifica la experiencia en la lectura y se disfruta más.

+ +

En HTML, cada párrafo tiene que estar delimitado por un elemento {{HTMLElement("p")}}, como en este ejemplo:

+ +
<p>Soy un párrafo, ¡desde luego que lo soy!</p>
+ +

Cada sección tiene que estar delimitada por un elemento de encabezado:

+ +
<h1>Yo soy el título de la historia</h1>
+ +

Hay seis elementos de encabezado: {{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}} y {{HTMLElement("h6")}}. Cada elemento representa un nivel de contenido diferente en el documento; <h1> representa el título principal, <h2> representa el subtítulo, <h3> representa el subtítulo del subtítulo, y así sucesivamente.

+ +

Cómo establecer la estructura jerárquica

+ +

Por ejemplo, en esta historia, <h1> representa el título de la historia, <h2> representará el título de cada capítulo y <h3> las diferentes secciones del capítulo, y así sucesivamente.

+ +
<h1>El agujero aplastante</h1>
+
+<p>Por Chris Mills</p>
+
+<h2>Capítulo 1: La oscura noche</h2>
+
+<p>Era una noche oscura. En algún lugar, un búho ululó. La lluvia azotó el ...</p>
+
+<h2>Capítulo 2: El silencio eterno</h2>
+
+<p>Nuestro protagonista ni susurrar pudo al ver esa sombría figura ...</p>
+
+<h3>El espectro habla</h3>
+
+<p>Habían pasado varias horas más, cuando de repente el espectro se incorporó y exclamó: "¡Por favor, ten piedad de mi alma!"</p>
+ +

Realmente es a tu elección lo que cada elemento involucrado represente, siempre y cuando la jerarquía tenga sentido. Solo es necesario que tengas en cuenta unas pocas buenas prácticas mientras creas la estructura:

+ + + +

¿Por qué necesitamos estructura?

+ +

Para responder a esta cuestión, echemos un vistazo a text-start.html; el apartado inicial de nuestro ejemplo en curso para este artículo (una buena receta de hummus). Debes guardar una copia de este archivo en tu ordenador porque después la necesitarás para los ejercicios prácticos. El cuerpo (<body>) de este documento incluye varios elementos de contenido que no están marcados de ninguna manera pero están separados por saltos de línea (se ha pulsado Intro/Retorno para continuar en la siguiente línea).

+ +

Sin embargo, cuando abres el documento en tu navegador, verás que el texto aparece... ¡como una masa enorme!

+ +

Una página web que muestra un muro de texto sin formato, porque no hay elementos en la página para estructurarlo.

+ +

Esto se debe a que no hay elementos que den estructura al contenido, por lo que el navegador no sabe qué es un encabezado y qué es un párrafo. Además:

+ + + +

Por lo tanto, debemos dar a nuestro contenido una estructura definida.

+ +

Aprendizaje Activo: Dar estructura a nuestro contenido

+ +

Pasemos directamente a un ejemplo real. En el ejemplo de abajo, añade elementos al texto en bruto en el campo Código editable para que en el campo Salida en vivo aparezcan como un encabezado y dos párrafos.

+ +

Si te equivocas, siempre puedes restablecer el código anterior pulsando el botón Restablecer. Si encallas, pulsa el botón Mostrar solución para ver la respuesta...

+ + + +

{{ EmbedLiveSample('Código_reproducible', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

¿Por qué necesitamos semántica?

+ +

Contamos con la semántica para todo lo que nos rodea. Nos basamos en experiencias previas para conocer la función de cada objeto cotidiano; cuando miramos un objeto, sabemos cuál debe ser su función. Entonces, por ejemplo, esperamos que un semáforo en rojo signifique "alto" y que un semáforo en verde signifique "avance". Las cosas se pueden complicar muy rápidamente si se aplica la semántica incorrecta. (¿Algún país usa rojo para significar "avance"? Esperemos que no).

+ +

De manera similar, debemos asegurarnos de que utilizamos los elementos adecuados y damos a nuestro contenido el significado y función correctos y la apariencia adecuada. En este mismo sentido, el elemento {{HTMLElement("h1")}} es un elemento semántico que da al texto al que delimita la función (o significado) de un titular de primer nivel en tu página.

+ +
<h1>Este es un titular de primer nivel</h1>
+ +

De manera predeterminada, el navegador le asignará una fuente de gran tamaño para darle el aspecto de un titular (aunque se le podrá dar el estilo que se quisiera usando CSS). Lo más importante es que su valor semántico se va a usar de diferente manera, por ejemplo, por los motores de búsqueda y los lectores de pantalla (como se mencionó antes).

+ +

Por otra parte, podrías hacer que cualquier elemento parezca un titular de primer rango. Considera lo siguiente:

+ +
<span style="font-size: 32px; margin: 21px 0;">¿Es este un titular de primer rango?</span>
+ +

Este es un elemento {{HTMLElement("span")}}. No tiene semántica. Se usa para delimitar contenido cuando se le quiere aplicar CSS (o tratarlo con JavaScript) sin proporcionarle ningún significado extra (encontrarás más información sobre este tipo de elemento más adelante en el curso). Hemos aplicado CSS a este elemento para que parezca un titular de primer nivel, pero al no tener valor semántico, no tiene ninguna de las ventajas añadidas que hemos descrito antes. Es una buena idea usar el elemento HTML apropiado para cada tarea.

+ +

Listas

+ +

Ahora volvamos nuestra atención hacia las listas. Las listas están en todos los aspectos de nuestra vida: desde la lista de compras a la lista de instrucciones que sigues inconscientemente para llegar a casa todos los días, o las listas de instrucciones que sigues en estos tutoriales. Las listas están en todos lados en la web también y hay tres diferentes tipos de las que nos vamos a ocupar.

+ +

Listas no ordenadas

+ +

Las listas no ordenadas se usan para marcar listas de artículos cuyo orden no es importante. Tomemos como ejemplo una lista de compras:

+ +
leche
+huevos
+pan
+hummus
+ +

Cada lista desordenada comienza con un elemento {{HTMLElement("ul")}} («unordered list») que delimita todos los elementos de la lista:

+ +
<ul>
+leche
+huevos
+pan
+hummus
+</ul>
+ +

El siguiente paso es delimitar cada artículo de la lista con un elemento {{HTMLElement("li")}} («list item»).

+ +
<ul>
+  <li>leche</li>
+  <li>huevos</li>
+  <li>pan</li>
+  <li>hummus</li>
+</ul>
+ +

Aprendizaje activo: marcar una lista no ordenada

+ +

Edita el siguiente ejemplo para crear tu propia lista HTML no ordenada.

+ + + +

{{ EmbedLiveSample('Código_reproducible_2', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Listas ordenadas

+ +

Las listas ordenadas son aquellas en las que el orden de los elementos importa. Tomemos como ejemplo una lista de instrucciones para seguir un itinerario:

+ +
Conduce hasta el final de la calle
+Gira a la derecha
+Sigue derecho por las dos primeras glorietas
+Gira a la izquierda en la tercer glorieta
+El colegio está a la derecha, 300 metros más adelante
+ +

La estructura de marcado es la misma que para las listas no ordenadas, excepto que debes delimitar los elementos de la lista con una etiqueta {{HTMLElement("ol")}} («ordered list»), en lugar de <ul>:

+ +
<ol>
+  <li>Conduce hasta el final de la calle</li>
+  <li>Gira a la derecha</li>
+  <li>Sigue derecho por las dos primeras glorietas</li>
+  <li>Gira a la izquierda en la tercer glorieta</li>
+  <li>El colegio está a tu derecha, 300 metros más adelante</li>
+</ol>
+ +

Aprendizaje activo: Marcar una lista ordenada

+ +

Edita el siguiente ejemplo para crear tu propia lista ordenada en HTML.

+ + + +

{{ EmbedLiveSample('Código_reproducible_3', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Aprendizaje activo: marcar la página de tu receta

+ +

Llegados a este punto del artículo, tienes toda la información necesaria para marcar la página de ejemplo con tu receta. Puedes escoger entre guardar una copia local del archivo inicial text-start.html y trabajar en él, o hacerlo sobre el ejemplo editable de abajo. Probablemente sea mejor trabajar en tu copia local porque podrás guardar tu progreso, mientras que si lo haces sobre el ejemplo editable, los cambios se perderán la próxima vez que cargues la página. Ambos métodos tienen pros y contras.

+ + + +

{{ EmbedLiveSample('Código_reproducible_4', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Si encallas, siempre puedes pulsar el botón Mostrar solución o comprobar el ejemplo completo text-complete.html en nuestro repositorio de Github.

+ +

Listas anidadas

+ +

Es perfectamente correcto anidar una lista dentro de otra. Posiblemente quieras tener subelementos bajo elementos de rango superior. Tomemos la segunda lista de nuestro ejemplo de la receta:

+ +
<ol>
+  <li>Pela el ajo y picarlo en trozos gruesos.</li>
+  <li>Retira las semillas y el tallo del pimiento, y cortarlo en trozos gruesos.</li>
+  <li>Mete todos los alimentos en un procesador de alimentos.</li>
+  <li>Pica todos los ingredientes hasta conseguir una pasta.</li>
+  <li>Si deseas un hummus "grueso", procésalo corto tiempo.</li>
+  <li>Pica durante más tiempo si se desea obtener un hummus "suave".</li>
+</ol>
+ +

Puesto que los dos últimos elementos están estrechamente relacionados con el elemento anterior (se leen como subinstrucciones u opciones que encajan bajo ese elemento), puede tener sentido anidarlos dentro de su propia lista no ordenada e introducir esa lista bajo el cuarto elemento. Tendría el siguiente aspecto:

+ +
<ol>
+  <li>Pela el ajo y picarlo en trozos gruesos.</li>
+  <li>Retira las semillas y el tallo del pimiento, y cortarlo en trozos gruesos.</li>
+  <li>Mete todos los alimentos en un procesador de alimentos.</li>
+  <li>Procesa todos los ingredientes hasta conseguir una pasta.
+    <ul>
+      <li>Si deseas un hummus "grueso", procésalo corto tiempo.</li>
+      <li>Pica durante más tiempo si se desea obtener un hummus "suave".</li>
+    </ul>
+  </li>
+</ol>
+ +

Vuelve al ejemplo anterior y reescribe la lista de este modo.

+ +

Énfasis e importancia

+ +

En el lenguaje humano, a menudo enfatizamos ciertas palabras para alterar el significado de una frase, y a menudo queremos destacar ciertas palabras como importantes o diferentes en algún sentido. HTML nos dota de diversos elementos semánticos que nos permiten destacar contenido textual con tales efectos, y en esta sección veremos los más comunes.

+ +

Énfasis

+ +

Cuando queremos dar énfasis al lenguaje hablado, acentuamos ciertas palabras y así alteramos sutilmente el significado de lo que decimos. De manera similar, en el lenguaje escrito ponemos palabras en cursiva para destacarlas. Por ejemplo, las dos siguientes frases tienen diferente significado:

+ +

Me alegro de que no llegues tarde.

+ +

Me alegro de que no llegues tarde.

+ +

La primera frase suena aliviada porque la persona no llega tarde. Por el contrario, la segunda suena sarcástica y un tanto pasivo-agresiva, expresa molestia porque la persona ha llegado algo tarde.

+ +

En HTML usamos el elemento {{HTMLElement("em")}} («emphasis») para marcar estos casos. El documento logra entonces transmitir una lectura más interesante y además así lo reconocen los lectores de pantalla, que lo expresan con un diferente tono de voz. El navegador, de manera predeterminada, aplica el estilo de letra itálica, pero no debes utilizar esta etiqueta solamente para establecer el estilo de letra itálica. Para usar ese estilo, debes utilizar únicamente la etiqueta del elemento {{HTMLElement("span")}} y algo de CSS u otra etiqueta con el elemento {{HTMLElement("i")}} (ve abajo).

+ +
<p>Me <em>alegro</em> de que no llegues <em>tarde</em>.</p>
+ +

Importancia fuerte

+ +

Para enfatizar palabras importantes al hablar solemos acentuarlas, y al escribir lo hacemos en estilo negrita. Por ejemplo:

+ +

Este líquido es altamente tóxico.

+ +

Cuento contigo. ¡No llegues tarde!

+ +

En HTML usamos el elemento {{HTMLElement("strong")}} (importancia fuerte) para marcar tales expresiones. El documento resulta entonces más útil, y de nuevo los lectores de pantalla reconocen estos elementos y el tono de voz cambia a uno más fuerte. El estilo negrita es el que aplican los navegadores por omisión, pero no debes usar esta etiqueta solamente para aplicar este estilo. Para hacer eso usa el elemento {{HTMLElement("span")}} y CSS, o un elemento {{HTMLElement("b")}} (ve más abajo).

+ +
<p>Este líquido es <strong>altamente tóxico</strong>.</p>
+
+<p>Cuento contigo. <strong>¡No llegues tarde!</strong></p>
+ +

Puedes anidar elementos de énfasis dentro de elementos de importancia y viceversa si lo deseas:

+ +
<p>Este líquido es <strong>altamente tóxico</strong> —
+si lo bebes, <strong>podrías <em>morir</em></strong>.</p>
+ +

Aprendizaje activo: ¡Seamos importantes!

+ +

En esta sección de aprendizaje activo te proporcionamos un ejemplo editable. Practica un poco añadiendo algo de énfasis e importancia a las palabras que creas que lo necesitan.

+ + + +

{{ EmbedLiveSample('Código_reproducible_5', 700, 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Cursiva, negrita, subrayado...

+ +

Los elementos que hemos comentado hasta ahora tienen asociada una semántica clara. La situación con {{HTMLElement("b")}} (negrita o «bold»), {{HTMLElement("i")}} (cursiva o «italic») y{{HTMLElement("u")}} (subrayado o «underline») es algo más complicada. Surgieron para que las personas pudieran escribir textos en negrita, cursiva o subrayado en un tiempo en el que pocos navegadores o ninguno admitían el CSS. Elementos como estos, que solo afectan a la presentación y no a la semántica, se conocen como elementos de presentación y no se deberían usar porque, como hemos visto, la semántica es muy importante para la accesibilidad y el SEO, entre otros aspectos.

+ +

HTML5 redefinió los elementos <b>, <i> y <u> con roles semánticos nuevos un tanto confusos.

+ +

Esta es la regla de oro: el uso de <b>, <i> o <u> resulta adecuado cuando transmiten el significado que suele transmitir el uso tradicional de las negritas, itálicas o el subrayado, si no hay ningún otro elemento que resulte más adecuado. Sin embargo, siempre resulta crítico mantener una actitud orientada a la accesibilidad. El concepto de itálica no es demasiado útil para las personas que usan lectores de pantalla o para las personas que utilizan un sistema de escritura distinto del alfabeto latino.

+ + + +
+

Una observación prudente acerca del subrayado: La gente suele asociar estrechamente el subrayado con los hipervínculos. Por ello en la web es mejor reservar el subrayado para los enlaces. Utiliza el elemento {{HTMLElement('u')}} cuando resulte apropiado semánticamente, pero considera usar CSS para cambiar el subrayado predeterminado por algo más adecuado en la web. El siguiente ejemplo ilustra cómo lo puedes hacer.

+
+ +
<!-- nombres científicos -->
+<p>
+  El colibrí garganta de rubí (<i>Archilochus colubris</i>)
+  es el colibrí más común en el este de América del Norte.
+</p>
+
+<!-- extranjerismos -->
+<p>
+  El menú era un mar de palabras exóticas como <i lang="uk-latn">vatrushka</i>,
+  <i lang="id">nasi goreng</i> y <i lang="fr">soupe à l'oignon</i>.
+</p>
+
+<!-- un error ortográfico reconocido -->
+<p>
+  Algún día aprenderé a deletrear mejor.
+</p>
+
+<!-- Palabras clave destacadas en una serie de instrucciones -->
+<ol>
+  <li>
+    <b>Corta</b> dos piezas de la hogaza de pan.
+  </li>
+  <li>
+    <b>Inserta</b> una rodaja de tomate y una hoja de
+    lechuga entre las rebanadas de pan.
+  </li>
+</ol>
+ +

¡Pon a prueba tus habilidades!

+ +

Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Encontrarás más ejercicios con los que comprobar que has retenido esta información antes de seguir adelante en {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Test_your_skills:_HTML_text_basics", "Pon a prueba tus habilidades: Prueba de conocimientos básicos de HTML")}}.

+ +

Resumen

+ +

¡Eso es todo por ahora! Este artículo debería haberte dado una buena idea de cómo comenzar a marcar texto en HTML y te ha presentado algunos de los elementos más importantes en este ámbito. Hay muchos más elementos semánticos para desarrollar en esta área, y veremos muchos más en nuestro artículo {{web.link("/en-US/docs/Learn/HTML/Introduction_to_HTML/Advanced_text_formatting", "Formateo de texto avanzado")}}, más adelante en el curso. En el siguiente artículo, veremos en detalle cómo {{web.link("/es/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "crear hipervínculos")}}, posiblemente el más importante elemento en la web.

+ +

{{PreviousMenuNext("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks", "Learn/HTML/Introduction_to_HTML")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html b/files/es/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html new file mode 100644 index 0000000000..5169cfc976 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/adding_vector_graphics_to_the_web/index.html @@ -0,0 +1,366 @@ +--- +title: Agregar Gráficos Vectoriales a la Web +slug: Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web +tags: + - Aprender + - Guía + - HTML + - Imagenes + - Principiante + - Raster + - SVG + - Vector + - graficos + - iframe + - img +translation_of: Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
+ +
+

Los gráficos vectoriales son muy útiles en muchas circunstancias — tienen tamaño de archivo pequeños y son altamente escalables, por lo que no se pixelan cuando se amplían a un tamaño más grande. En este artículo le mostraremos cómo incluir uno en su página web.

+
+ + + + + + + + + + + + +
Prerequisitos:Debe conocer los conceptos básicos de HTML y cómo insertar imágenes en su documento
Objetivo:Aprender a incrustar una imagen SVG (vector) en una página web.
+ +
+

Nota: Este artículo no tiene la intención de enseñarte SVG; solo mostrarte qué es, y cómo agregarlo a las páginas web.

+
+ +

¿Qué son los gráficos vectoriales?

+ +

En la web, trabajarás con dos tipos de imágenes — imágenes rasterizadas, e imágenes vectoriales:

+ + + +

Para darte una idea de la diferencia entre los dos, veamos un ejemplo. Puede encontrar este ejemplo en vivo en nuestro repositorio de Github como vector-versus-raster.html — muestra dos imágenes aparentemente idénticas una al lado de la otra, de una estrella roja con una sombra negra. La diferencia es que el de la izquierda es un PNG y el de la derecha es una imagen SVG.

+ +

La diferencia se hace evidente cuando amplía la página — la imagen PNG se pixela a medida que se acerca porque contiene información sobre dónde debería estar cada píxel (y de qué color). Cuando se amplía, cada píxel simplemente aumenta de tamaño para llenar varios píxeles en la pantalla, por lo que la imagen comienza a verse borrosa. Sin embargo, la imagen vectorial sigue luciendo agradable y nítida, porque no importa el tamaño que tenga, los algoritmos se utilizan para resolver las formas en la imagen, y los valores simplemente se escalan a medida que aumenta.

+ +

Two star images

+ +

Two star images zoomed in, one crisp and the other blurry

+ +
+

Nota: Las imágenes de arriba son en realidad todos PNG, con la estrella de la izquierda en cada caso representando una imagen rasterizada y la estrella de la derecha representando una imagen vectorial. Nuevamente, vaya a la demostración de vector-versus-raster.html para ver un ejemplo real.

+
+ +

Además, los archivos de imágenes vectoriales son mucho más ligeros que sus equivalentes ráster, porque solo necesitan contener un puñado de algoritmos, en lugar de información sobre cada píxel de la imagen individualmente.

+ +

¿Qué es SVG?

+ +

SVG es un lenguaje basado en {{glossary("XML")}}-para describir imágenes vectoriales. Básicamente es un marcado, como HTML, excepto que tiene muchos elementos diferentes para definir las formas que desea que aparezcan en su imagen y los efectos que desea aplicar a esas formas. SVG es para marcar gráficos, no contenido. En el extremo más simple del espectro, tienes elementos para crear formas simples, como {{svgelement("circle")}} and {{svgelement("rect")}}. Las funciones SVG más avanzadas incluyen {{svgelement("feColorMatrix")}} (transformar colores usando una matriz de transformación), {{svgelement("animate")}} (animar partes de su gráfico vectorial), and {{svgelement("mask")}} (aplica una máscara sobre la parte superior de tu imagen).

+ +

Como ejemplo simple, el siguiente código crea un círculo y un rectángulo:

+ +
<svg version="1.1"
+     baseProfile="full"
+     width="300" height="200"
+     xmlns="http://www.w3.org/2000/svg">
+  <rect width="100%" height="100%" fill="black" />
+  <circle cx="150" cy="100" r="90" fill="blue" />
+</svg>
+ +

Esto crea la siguiente salida:

+ +

{{ EmbedLiveSample('What_is_SVG', 300, 200, "", "", "hide-codepen-jsfiddle") }}

+ +

En el ejemplo anterior, puede tener la impresión de que SVG es fácil de codificar manualmente. Sí, puede codificar manualmente SVG simple en un editor de texto, pero para una imagen compleja, esto rápidamente comienza a ser muy difícil. Para crear imágenes SVG, la mayoría de la gente usa un editor de gráficos vectoriales como Inkscape o Illustrator. Estos paquetes le permiten crear una variedad de ilustraciones utilizando varias herramientas gráficas y crear aproximaciones de fotos (por ejemplo, la función Trazar mapa de bits de Inkscape).

+ +

SVG tiene algunas ventajas adicionales además de las descritas hasta ahora:

+ + + +

Entonces, ¿por qué alguien querría usar gráficos rasterizados sobre SVG? Bueno, SVG tiene algunas desventajas:

+ + + +

Los gráficos rasterizados son posiblemente mejores para imágenes de precisión complejas, como fotos, por las razones descritas anteriormente.

+ +
+

Nota: En Inkscape, guarde sus archivos como SVG simple para ahorrar espacio. Además, consulte este artículo que describe cómo preparar SVGs para la web.

+
+ +

Agregar SVG a sus páginas

+ +

En esta sección, veremos las diferentes formas en las que puede agregar gráficos vectoriales SVG a sus páginas web.

+ +

La forma rápida: {{htmlelement("img")}}

+ +

Para incrustar un SVG a través de un elemento {{htmlelement ("img")}}, solo necesita hacer referencia a él en el atributo src como es de esperar. Necesitará un atributo de altura o ancho (o ambos si su SVG no tiene una relación de aspecto inherente). Si aún no lo ha hecho, lea Imágenes en HTML.

+ +
<img
+    src="equilateral.svg"
+    alt="triangle with all three sides equal"
+    height="87"
+    width="100" />
+ +

Pros

+ + + +

Cons

+ + + +

Solución de problemas y compatibilidad con varios navegadores

+ +

Para los navegadores que no admiten SVG (IE 8 y versiones anteriores, Android 2.3 y versiones anteriores), puede hacer referencia a un PNG o JPG de su atributo src y usar un atributo {{htmlattrxref ("srcset", "img")}} ( que solo los navegadores recientes reconocen) para hacer referencia al SVG. Siendo este el caso, solo los navegadores compatibles cargarán el SVG; los navegadores más antiguos cargarán el PNG en su lugar:

+ +
<img src="equilateral.png" alt="triangle with equal sides" srcset="equilateral.svg">
+ +

También puede usar SVG como imágenes de fondo CSS, como se muestra a continuación. En el siguiente código, los navegadores más antiguos se quedarán con el PNG que entienden, mientras que los navegadores más nuevos cargarán el SVG:

+ +
background: url("fallback.png") no-repeat center;
+background-image: url("image.svg");
+background-size: contain;
+ +

Al igual que el método <img> descrito anteriormente, la inserción de SVG con imágenes de fondo CSS significa que el SVG no se puede manipular con JavaScript y también está sujeto a las mismas limitaciones de CSS.

+ +

Si sus SVG no se muestran en absoluto, podría deberse a que su servidor no está configurado correctamente. Si ese es el problema, este artículo le indicará la dirección correcta.

+ +

Cómo incluir código SVG dentro de su HTML

+ +

También puede abrir el archivo SVG en un editor de texto, copiar el código SVG y pegarlo en su documento HTML; esto a veces se denomina poner su SVG en línea o SVG en línea. Asegúrese de que su fragmento de código SVG comience y termine con las etiquetas <svg> </svg> (no incluya nada fuera de ellas). Aquí tiene un ejemplo muy simple de lo que puede pegar en su documento:

+ +
<svg width="300" height="200">
+    <rect width="100%" height="100%" fill="green" />
+</svg>
+
+ +

Pros

+ + + +

Cons

+ + + + + +

Cómo incrustar un SVG con un {{htmlelement("iframe")}}

+ +

Puede abrir imágenes SVG en su navegador al igual que las páginas web. Entonces, incrustar un documento SVG con un <iframe> se realiza tal como lo estudiamos en De <object> a <iframe>  otras tecnologías de incrustación.

+ +

Aquí hay una revisión rápida:

+ +
<iframe src="triangle.svg" width="500" height="500" sandbox>
+    <img src="triangle.png" alt="Triangle with three unequal sides" />
+</iframe>
+ +

Este definitivamente no es el mejor método para elegir:

+ +

Cons

+ + + +

Aprendizaje activo: jugar con SVG

+ +

En esta sección de aprendizaje activo, nos gustaría que simplemente probaras a jugar con algunos SVG por diversión. En la entrada a continuación, verá que ya le hemos proporcionado algunas muestras para que pueda comenzar. También puedes ir a la Referencia de Elementos SVG, descubrir más detalles sobre otros juguetes que puedes usar en SVG y probarlos también. Esta sección trata sobre cómo practicar sus habilidades de investigación y divertirse.

+ +

Si se queda atascado y no puede hacer que su código funcione, siempre puede restablecerlo con el botón Restablecer.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 500, "", "", "hide-codepen-jsfiddle") }}

+ +

Resumen

+ +

Este artículo le ha proporcionado un recorrido rápido por qué son los gráficos vectoriales y SVG, por qué es útil conocerlos y cómo incluir SVG en sus páginas web. Nunca tuvo la intención de ser una guía completa para aprender SVG, solo un indicador para que sepa qué es SVG si lo encuentra en sus viajes por la Web. Así que no se preocupe si todavía no siente que es un experto en SVG. Hemos incluido algunos enlaces a continuación que pueden ayudarlo si desea ir y obtener más información sobre cómo funciona.

+ +

En el próximo artículo de este módulo, exploraremos las imágenes adaptables en detalle, observando las herramientas que tiene HTML para permitirle hacer que sus imágenes funcionen mejor en diferentes dispositivos.

+ +

Vea también

+ + + +

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/multimedia_and_embedding/images_in_html/index.html b/files/es/learn/html/multimedia_and_embedding/images_in_html/index.html new file mode 100644 index 0000000000..22734a9b24 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/images_in_html/index.html @@ -0,0 +1,510 @@ +--- +title: Imágenes en HTML +slug: Learn/HTML/Multimedia_and_embedding/Images_in_HTML +tags: + - Aprendiz + - Article + - HTML + - Imagenes + - captions + - figcaption + - img + - pie de imagen + - subtítulos + - texto alt +translation_of: Learn/HTML/Multimedia_and_embedding/Images_in_HTML +--- +
+

{{LearnSidebar}}

+ +

{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}

+
+ +

Al principio, la web solo era texto y resultaba más bien aburrido. Afortunadamente, no pasó mucho tiempo antes de que se añadiera la capacidad de insertar imágenes (y otros tipos de contenido más interesantes) en las páginas web. Hay otros tipos de elementos multimedia que tener en cuenta, pero es lógico comenzar con el humilde elemento {{htmlelement("img")}} utilizado para insertar una imagen simple en una página web. En este artículo, veremos en detalle cómo usar este elemento, incluidos sus conceptos básicos y cómo añadir pies de imagen usando {{htmlelement("figure")}} y explicaremos cómo se relaciona con las imágenes de fondo en CSS.

+ +
+ + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, tener el software básico instalado, conocimientos básicos de cómo trabajar con archivos, estar familiarizado con los principios básicos de HTML (como se describe en Empezar con el HTML).
Objetivo:Aprender cómo insertar imágenes simples en HTML y añadirles pies de imagen, y cómo se relacionan las imágenes HTML con las imágenes de fondo de CSS.
+ +

¿Cómo ponemos una imagen en una página web?

+ +

Para poner una imagen simple en una página web, utilizamos el elemento {{htmlelement("img")}}. Se trata de un elemento vacío (lo que significa que no contiene texto o etiqueta de cierre) que requiere de por lo menos de un atributo para ser utilizado: src (a veces denominado por su nombre completo, source). El atributo src contiene una ruta que apunta a la imagen que quieres poner en la página, que puede ser una URL relativa o absoluta, de la misma forma que el elemento {{htmlelement("a")}} contiene los valores del atributo href.

+ +
+

Nota: Deberías leer Inicio rápido a las URL y rutas para refrescar tu memoria sobre URL relativas y absolutas antes de continuar.

+
+ +

Por ejemplo, si tu imagen se llama dinosaur.jpg, y está en el mismo directorio que tu página HTML, deberás incrustar la imagen de la siguiente manera:

+ +
<img src="dinosaur.jpg">
+ +

Si la imagen estaba en el subdirectorio images, que estaba en el mismo directorio que la página HTML (lo que Google recomienda con fines de indización y posicionamiento en buscadores {{glossary("SEO")}}), entonces deberías incrustar la imagen así:

+ +
<img src="images/dinosaur.jpg">
+ +

y así sucesivamente.

+ +
+

Nota: Los motores de búsqueda también leen los nombres de archivo de imagen y esto cuenta para el SEO.  Por lo tanto, dale a tu imagen un nombre descriptivo; dinosaur.jpg es mejor que img835.png.

+
+ +

Puedes incrustar la imagen usando la URL absoluta, por ejemplo:

+ +
<img src="https://www.example.com/images/dinosaur.jpg">
+ +

Pero esto no tiene sentido, solo hace que el navegador trabaje más buscando la dirección IP desde el servidor DNS cada vez, etc. Casi siempre mantendrás las imágenes para tu sitio web en el mismo servidor de tu HTML.

+ +
+

Advertencia: La mayoría de imágenes tienen derechos de autor. No muestres una imagen en tu página web a menos que:
+
+ 1) seas dueño de la imagen,
+ 2) tengas permiso escrito explícito del dueño de la imagen o 
+ 3) tengas suficientes pruebas de que la imagen es de dominio público.
+
+ El incumplimiento de las normas de los derechos de autor es un acto ilegal y poco ético. Por lo tanto, no apuntes nunca tu atributo src a una imagen que esté alojada en un sitio web si no tienes el permiso para hacerlo. Esto se llama hotlinking. Asimismo es ilegal robar el ancho de banda de alguien.  Además, ralentiza tu página y te deja sin control sobre la imagen si la eliminan o reemplazan por otra que incluso podría resultar embarazosa.

+
+ +

Nuestro código anterior debería darnos el resultado siguiente:

+ +

A basic image of a dinosaur, embedded in a browser, with Images in HTML written above it

+ +
+

Nota: Los elementos como {{htmlelement("img")}} y {{htmlelement("video")}} a veces se denominan elementos reemplazados. Esto se debe a que el tamaño y el contenido del elemento se especifican en un recurso externo (como un archivo de imagen o video),  no en el contenido del elemento en sí.

+
+ +
+

Nota: Puedes encontrar el ejemplo terminado de esta sección en Github (consulta también el código fuente).

+
+ +

Texto alternativo

+ +

El próximo atributo que veremos es  alt. Su valor debe ser una descripción textual de la imagen para usarla en situaciones en que la imagen no puede ser vista/mostrada o tarde demasiado en mostrarse por una conexión lenta a internet. Por ejemplo, nuestro código anterior podría modificarse así:

+ +
<img src="images/dinosaur.jpg"
+     alt="La cabeza y el torso de un esqueleto de dinosaurio;
+           tiene una cabeza grande con dientes largos y afilados">
+ +

La forma más fácil de probar el texto alt es escribir mal el nombre de archivo. Si, por ejemplo, escribimos el nombre archivo de nuestra imagen como dinosooooor.jpg, el navegador no podrá mostrar la imagen, en su lugar mostrará el texto alternativo:

+ +

The Images in HTML title, but this time the dinosaur image is not displayed, and alt text is in its place.

+ +

¿Por qué vas a ver o necesitar el texto alternativo? Puede ser por varias razones:

+ + + +

¿Qué hay que escribir exactamente en el atributo alt? Esto depende en primer lugar de por qué la imagen está en ese lugar. En otras palabras, qué se pierde si la imagen no aparece:

+ + + +

En el fondo, la clave es ofrecer una experiencia usable, incluso cuando las imágenes no puedan verse. Esto asegura que ningún usuario pierda ninguna parte del contenido. Desactiva las imágenes en tu navegador y observa cómo se ven las cosas. Te darás cuenta de lo útil que resulta el texto alternativo cuando no es posible ver la imagen.

+ +
+

Nota: Consulta nuestra guía de texto alternativo para obtener más información.

+
+ +

Anchura y altura

+ +

Puedes usar los atributos  ancho (width) y alto (height) para especificar la anchura y altura de tu imagen. Puedes encontrar el ancho y el alto de tu imagen de diversas maneras. Por ejemplo, en Mac puedes usar  Cmd + I  para mostrar información del archivo de imagen. Volviendo a nuestro ejemplo, podríamos hacer esto:

+ +
<img src="images/dinosaur.jpg"
+     alt="La cabeza y el torso de un esqueleto de dinosaurio;
+           tiene una cabeza grande con dientes largos y afilados"
+     width="400"
+     height="341">
+ +

Esto no proporciona una gran diferencia en la pantalla en circunstancias normales. Pero si la imagen no se muestra, por ejemplo, porque el usuario acaba de acceder a la página y esta aún no se ha cargado, observarás que el navegador reserva un espacio para la imagen:

+ +

The Images in HTML title, with dinosaur alt text, displayed inside a large box that results from width and height settings

+ +

Hacerlo así es bueno porque la página se carga con mayor rapidez y fluidez.

+ +

Sin embargo, no deberías alterar el tamaño de tus imágenes utilizando atributos HTML. Las imágenes podrían verse granulosas y borrosas si estableces un tamaño demasiado grande; o bien demasiado pequeñas, y se desperdiciaría ancho de banda descargando una imagen que no se ajusta a las necesidades del usuario. La imagen también podría quedar distorsionada, si no mantienes la proporción de aspecto correcta. Deberías utilizar un editor de imágenes, para dar a tu imagen el tamaño adecuado, antes de colocarla en tu página web.

+ +
+

Nota: Si tienes que alterar el tamaño de una imagen es mejor usar CSS.

+
+ +

Título de imágenes

+ +

Al igual que con los enlaces, también puedes añadir atributos title a las imágenes para proporcionar más información de ayuda si es necesario. En nuestro ejemplo, podríamos hacer esto:

+ +
<img src="images/dinosaur.jpg"
+     alt="La cabeza y el torso de un esqueleto de dinosaurio;
+           tiene una cabeza grande con dientes largos y afilados"
+     width="400"
+     height="341"
+     title="Exposición de un T-Rex en el museo de la Universidad de Manchester.">
+ +

Esto nos da una etiqueta de ayuda (tooltip) como las de los enlaces:

+ +

The dinosaur image, with a tooltip title on top of it that reads A T-Rex on display at the Manchester University Museum

+ +

Sin embargo, no se recomienda incluir esta propiedad en las imágenes. title presenta algunos problemas de accesibilidad, principalmente porque los lectores de pantalla (screen readers) tienen un comportamiento imprevisible y la mayoría de navegadores no la mostrarán a menos que pases el ratón por encima de la imagen (y por tanto es inútil para quien usa teclado). Si estás interesado en esta cuestión, puedes leer el artículo The Trials and Tribulations of the Title Attribute de Scott O’Hara.

+ +

Lo mejor es incluir dicha información en el texto principal del artículo, en lugar de adjuntarla en la imagen.

+ +

Aprendizaje activo: incrustar imágenes

+ +

¡Ahora te toca jugar a ti! Esta sección de aprendizaje activo te mantendrá activo con un ejercicio sencillo de incrustado. Te proporcionamos una etiqueta básica {{htmlelement ("img")}} y nos gustaría que incrustes la imagen ubicada en la URL siguiente:

+ +

https://raw.githubusercontent.com/mdn/learning-area/master/html/multimedia-and-embedding/images-in-html/dinosaur_small.jpg

+ +

Ya hemos dicho que nunca se apuntará a imágenes de otros servidores (hotlink), pero esto es solo con fines de aprendizaje, por lo que te lo vamos a dejar hacer por esta vez.

+ +

También nos gustaría que hagas lo siguiente:

+ + + +

Si te equivocas, puedes volver a empezar pulsando el botón Reiniciar. Si te encallas, pulsa el botón Mostrar la solución para ver la solución:

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 350, "", "", "hide-codepen-jsfiddle") }}

+ +

Comentar imágenes con figure y figcaption

+ +

Hay varias formas en que puedes añadir un pie a tu imagen. Por ejemplo, nada te impediría hacer esto:

+ +
<div class="figure">
+  <img src="images/dinosaur.jpg"
+       alt="La cabeza y el torso de un esqueleto de dinosaurio;
+           tiene una cabeza grande con dientes largos y afilados"
+       width="400"
+       height="341">
+
+  <p>Exposición de un T-Rex en el museo de la Universidad de Manchester.</p>
+</div>
+ +

Esto está bien. Incluye el contenido que se necesita y es muy personalizable con CSS. Pero hay un problema: no hay nada que vincule semánticamente la imagen con su título, lo que puede causar problemas a los lectores de pantalla. Por ejemplo, cuando hay 50 imágenes y leyendas, ¿qué leyenda se corresponde con cada imagen?

+ +

Una solución mejor es utilizar los elementos HTML5 {{htmlelement("figure")}} y {{htmlelement("figcaption")}}. Estos se crearon exactamente para este propósito: proporcionar un contenedor semántico para las figuras y vincular claramente la figura con el pie. Nuestro ejemplo anterior, podría reescribirse así:

+ +
<figure>
+  <img src="images/dinosaur.jpg"
+       alt="La cabeza y el torso de un esqueleto de dinosaurio;
+           tiene una cabeza grande con dientes largos y afilados" width="400"
+       height="341">
+
+  <figcaption>Exposición de un T-Rex en el museo de la Universidad de Manchester.</figcaption>
+</figure>
+ +

El elemento {{htmlelement("figcaption")}} dice al navegador, o a alguna tecnología de apoyo, que el texto que contiene describe la imagen que está contenida en el elemento {{htmlelement("figure")}}.

+ +
+

Nota: Desde el punto de vista de la accesibilidad, los pies de imagen y el texto alternativo {{htmlattrxref('alt','img')}} cumplen funciones diferentes. Los pies de imagen benefician incluso a quien puede ver la imagen, mientras que el texto {{htmlattrxref('alt','img')}} proporciona la misma función en una imagen ausente. Por tanto, los subtítulos y el texto alt no deberían decir lo mismo, porque ambos aparecen si la imagen no se muestra. Desactiva las imágenes en tu navegador y observa el resultado.

+
+ +

El elemento figure no ha de contener una imagen necesariamente. Es una unidad de contenido independiente que:

+ + + +

Un elemento figure podría contener varias imágenes, un trozo de código, audio, video, ecuaciones, una tabla, o cualquier otra cosa.

+ +

Aprendizaje activo: crear un elemento figure

+ +

En esta sección de aprendizaje activo, te pedimos que tomes el código finalizado de la sección de aprendizaje activo anterior y lo conviertas en un elemento figure:

+ + + +

Si te equivocas, siempre puedes volver a empezar pulsando el botón Reiniciar. Si te quedas atascado, presiona el botón Ver solución para ver la respuesta:

+ + + +

{{ EmbedLiveSample('Playable_code_2', 700, 350, "", "", "hide-codepen-jsfiddle") }}

+ +

Imágenes de fondo CSS

+ +

También puedes usar CSS para insertar imágenes en páginas web (y JavaScript, pero eso ya es otra historia). La propiedad CSS {{cssxref("background-image")}} y las demás propiedades  background-* se usan para controlar la colocación de la imagen de fondo. Por ejemplo, para poner una imagen de fondo en cada párrafo de una página, podríamos hacer esto:

+ +
p {
+  background-image: url("images/dinosaur.jpg");
+}
+ +

La imagen resultante, podría decirse que es más fácil de posicionar y controlar que una imagen HTML. Entonces ¿para qué molestarse usando imágenes HTML? Como se sugiere arriba, las imágenes de fondo CSS son solo para decoración. Si tan solo quieres añadir algo bonito para mejorar visualmente tu página, están bien. Sin embargo, no tienen ningún significado semántico. No pueden tener su equivalente en texto, son invisibles a los lectores de pantalla, etc. ¡Es entonces cuando las imágenes HTML triunfan!

+ +

En resumen: si una imagen tiene significado en términos del contenido de tu página, entonces deberías usar una imagen HTML. Si la imagen es puramente decorativa, deberías usar imágenes de fondo CSS.

+ +
+

Nota: Aprenderás mucho más sobre las imágenes de fondo CSS en nuestro apartado CSS.

+
+ +

Esto es todo por ahora. Hemos expuesto en detalle los conceptos relativos a imágenes y subtítulos de imagen. En el próximo artículo, subiremos un nivel para insertar vídeo y audio en páginas web con HTML.

+ +

{{NextMenu("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding")}}

+ +

En este módulo

+ + +
diff --git a/files/es/learn/html/multimedia_and_embedding/index.html b/files/es/learn/html/multimedia_and_embedding/index.html new file mode 100644 index 0000000000..5e0ffe97a8 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/index.html @@ -0,0 +1,73 @@ +--- +title: Multimedia e inserción +slug: Learn/HTML/Multimedia_and_embedding +tags: + - Aprender + - Audio + - Codificación de Secuencia de comandos + - Evaluación + - Flash + - Gráficos vectoriales + - Guía + - HTML + - Imagenes + - Inserción + - Landing + - Mapa de Imágenes + - Multimedia + - Principiante + - SVG + - Video + - Web + - iframes + - img + - receptivo +translation_of: Learn/HTML/Multimedia_and_embedding +--- +

Hemos visto mucho texto hasta ahora en este curso, pero la web sería realmente aburrida solo usando textos. ¡Comencemos observando como hacer que la web cobre vida, con mucho más contenido interesante! Este módulo te acompañará a explorar maneras de usar HTML para incluir multimedia a tus páginas web, y las diferentes formas en la que podrás hacerlo, incluyendo como enlazar videos, audios e incluso otras páginas webs.

+ +

Requisitos previos

+ +

Antes de empezar con este módulo, deberías tener un buen conocimiento de las bases de HTML, enseñadas en Introducción a HTML. Si no has estado trabajando en este módulo (o alguno similar), ¡hazlo y luego vuelve!

+ +
+

Nota: Si estas trabajando en un ordenador/tablet/u otro dispositivo donde no puedas crear tus propios archivos, puedes probar (la mayoría de ellos) los ejemplos de código en programas online de codificado como JSBin o Glitch.

+
+ +

Guías

+ +

Este módulo contiene los siguientes artículos que te enseñarán todo lo fundamental sobre introducir multimedia en páginas web.

+ +
+
Imágenes en HTML
+
Hay otros tipos de multimedia a considerar, pero es logico empezar con el humilde elemento {{htmlelement("img")}}, usado para incorporar una imagen simple en una página web. En este artículo veremos cúmo usarlo en profundidad, incluyendo los conceptos básicos, y contenido independiente con título usando  {{htmlelement("figure")}}, y cómo relacionarlos con las imágenes de fondo de CSS.
+
Contenido de Audio y Video
+
A continuación, veremos como usar los elementos de HTML5 {{htmlelement("video")}} y {{htmlelement("audio")}}, para insertar video y audio en nuestras páginas, incluyendo conceptos básicos, proporcionando acceso a diferentes formatos de archivo para diferentes navegadores, agregando ilustraciones y subtítulos y cómo resolver inconvenientes en navegadores más antiguos.
+
De <object> a <iframe> - otras tecnologías de inserción
+
En este punto, nos gustaría dar un paso hacia un lado, mirando algunos de los elementos que te permiten insertar una amplia variedad de tipos de contenido en tus páginas web: los elementos {{htmlelement("iframe")}}, {{htmlelement("embed")}} y {{htmlelement("object")}}.
+ El elemento <iframe> nos permite incluir otras páginas web, y las otras dos permiten insertar archivos de formato PDF, SVG e incluso Flash -una tecnología que está a punto de desaparecer, pero que todavía puede verse de manera semi-regular-.
+
Añadiendo graficos vectoriales a la Web
+
Los gráficos vectoriales pueden ser muy útiles en ciertas situaciones. A diferencia de los formatos normales como PNG / JPG, estos no se distorsionan/pixelizan cuando se los amplían -pueden permanecer suaves cuando se escalan-. Este artículo te introduce al concepto de gráficos vectoriales y cómo incluir el popular formato {{glossary ("SVG")}} en páginas web.
+
Imagenes receptivas
+
En este artìculo, aprenderás acerca del concepto de imágenes receptivas -imágenes que pueden adaptarse en dispositivos con grandes diferencias de tamaños de pantalla, resoluciones y otras características-. Esto te ayudará a mejorar el rendimiento en diferentes dispositivos. Las imágenes receptivas son sólo una parte del diseño receptivo, un tópico que a futuro aprenderás en CSS.
+
+ +

Evaluaciones

+ +

Las siguientes evaluaciones pondrán a prueba tu comprensión de los conceptos básicos de HTML vistos en las guías anteriores.

+ +
+
Página de bienvenida de Mozilla
+
En esta evaluación, probaremos tu conocimiento de algunas de las técnicas observadas en los artículos de este módulo, ¡lo que te permitirá agregar algunas imágenes y videos a una página original de Mozilla!
+
+ +

Ver también

+ +
+
Agregar un mapa de visitas en la parte superior de una imagen
+
Los mapas de imágenes proporcionan un mecanismo para hacer diferentes partes de un enlace de imagen a diferentes lugares (piense en un mapa, vinculándolo a más información sobre cada país diferente al que haga clic). Esta técnica a veces puede ser útil.
+
Conceptos básicos de escritura web 2
+
+

Un excelente curso básico de la fundación Mozilla que explora y prueba algunas de las habilidades mencionadas en el módulo Multimedia e inclusión. Sumérgete en los aspectos básicos de la composición de páginas web, diseño de accesibilidad, uso compartido de recursos, uso de medios en línea y trabajo abierto (significa que tu contenido es libre de compartirse con otros).

+
+
diff --git a/files/es/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html b/files/es/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html new file mode 100644 index 0000000000..662d565e31 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/mozilla_splash_page/index.html @@ -0,0 +1,138 @@ +--- +title: Página de bienvenida de Mozilla +slug: Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page +tags: + - Codificación de Secuencia de comandos + - CodingScripting + - Evaluación + - HTML + - Imagenes + - Inserción + - JPEG + - Medidas + - Multimedia + - PNG + - Principiante + - Video + - iframe + - img + - receptivo + - src + - srcset +translation_of: Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}
+ +

En esta evaluación, pondremos a prueba tu conocimiento de algunas de las técnicas mostradas en los artículos de este módulo, ¡para que tú agregues algunas imágenes y videos a una página de bienvenida de Mozzilla!.

+ + + + + + + + + + + + +
Requisitos previos:Antes de intentar esta evaluación, ya deberías conocer el módulo de Multimedia e inserción.
Objetivo:Prueba cuánto sabes de la incorporación de imágenes y videos en páginas web, marcos y técnicas de imagen receptiva a HTML.
+ +

Punto de partida

+ +

Para comenzar esta evaluación, necesitas el HTML y todas las imágenes de mdn-splash-page-start que tienes en la carpeta de GitHub. Guarda el contenido de index.html en un archivo llamado index.html en tu disco local, en una nueva carpeta. Guarda pattern.png en la misma carpeta (haciendo click derecho en la imagen y seleccionando la opción guardar).

+ +

Accede a las diferentes imágenes en la carpeta de originals y guárdalas también de la misma manera. De momento puedes guardarlas en una carpeta diferente, ya que podrías necesitar modificarlas usando un editor de gráficos antes de que estén listas para usarlas.

+ +

También puedes usar una herramienta en línea como Glitch para crear tu ejemplo. Esto puede ser útil si quieres evaluarlo o pedir ayuda — consulta la sección  {{anch("Assessment or further help")}} al final de esta página.

+ +
+

Nota: El archivo HTML de ejemplo contiene bastante CSS para dar estilo a la página. No necesitas tocar el CSS, solo el HTML dentro del elemento {{htmlelement("body")}}, mientras que insertes el marcado correctamente, el estilo se mantendrá.

+
+ +

Resumen del proyecto

+ +

En esta evaluación, te presentamos una página de bienvenida de Mozzilla en su mayoría terminada, que tiene como objetivo decir algo agradable e interesante sobre lo que significa Mozilla, y proporcionar algunos enlaces a recursos adicionales. Desafortunadamente, aún no se han agregado imágenes o videos, ¡este es tu trabajo!. Debes añadir algunos elementos para que la página se vea bien y tenga sentido. Las siguientes subsecciones detallan lo que tienes que hacer:

+ +

Preparar las imágenes

+ +

Usa tu editor de imágenes favorito, y utiliza medidas de 400px de ancho y 120px de alto para:

+ + + +

Nómbralas por ejemplo, firefoxlogo400.png y firefoxlogo120.png.

+ +

Junto con mdn.svg, estas imágenes serán tus iconos para vincular a otros recursos, dentro del área further-info. Debes vincular al logo de Firefox en el encabezado del sitio. Guarda copias de todos estos dentro de la misma carpeta que index.html.

+ +

A continuación, crea una versión horizontal de 1200px de red-panda.jpg, y una versión vertical de 600px que muestre al panda en una toma de primer plano. Una vez más, ponle un nombre para que puedas identificarlos fácilmente. Guarda una copia de ambos en la misma carpeta que index.html.

+ +
+

Nota: Debes optimizar las imágenes JPG y PNG para que sean lo más pequeñas posible, viéndose bien. tinypng.com es un gran servicio para hacerlo fácilmente.

+
+ +

Añadir logo al encabezado

+ +

El elemento {{htmlelement("header")}}, añade el elemento {{htmlelement("img")}} que insertará la versión pequeña del logotipo de Firefox al encabezado.

+ +

Añadir un video al contenido del artículo principal

+ +

Justo dentro del elemento {{htmlelement("article")}} (debajo de la etiqueta de apertura), inserta el video de Youtube https://www.youtube.com/watch?v=ojcNcvb1olg, utilizando las herramientas de YouTube para generar el código. El video debe tener 400px de ancho.

+ +

Agregar imágenes receptivas a los enlaces de información adicional

+ +

 Dentro de {{htmlelement("div")}} con clase further-info encontrarás cuatro elementos {{htmlelement("a")}} -cada uno de los cuales vincula a una página interesante relacionada con Mozilla-. Para completar esta sección, debes insertar un elemento {{htmlelement("img")}} dentro de cada uno que contenga los atributos {{htmlattrxref("src", "img")}}, {{htmlattrxref("alt", "img")}}, {{htmlattrxref("srcset", "img")}} y {{htmlattrxref("sizes", "img")}}.

+ +

En cada caso, (excepto uno que es inherentemente receptivo) queremos que el navegador sirva la versión 120px cuando el ancho de la ventana de visualización sea de 500px o menos, o la versión de 400px en otro caso.

+ +

¡Asegúrate de hacer coincidir las imágenes correctas con los enlaces correctos!

+ +
+

Nota: para probar correctamente los ejemplos srcset/sizes necesitarás cargar tu sitio a un servidor (usar Github pages es una solución fácil y gratis), y desde allí puedes probar si funcionan correctamente usando herramientas de desarrollo del navegador como Firefox Network Monitor.

+
+ +

Un "red-panda" con arte dirigido

+ +

Dentro del elemento {{htmlelement("div")}} con clase red-panda, queremos insertar un elemento {{htmlelement("picture")}} que permita una imagen pequeña del panda si la ventana tiene 600px de ancho o menos, y la gran imagen del paisaje en caso contrario.

+ +

Ejemplo

+ +

Las siguientes capturas de pantalla muestran como debería verse la página de bienvenida después de haber sido marcada correctamente, en una pantalla ancha y estrecha.

+ +

A wide shot of our example splash page

+ +

A narrow shot of our example splash page

+ +

Evaluación o ayuda adicional

+ +

Si quieres evaluar tu trabajo, estás atorado o quieres pedir ayuda:

+ +
    +
  1. Pon tu trabajo en un editor en línea para compartir, como CodePen, jsFiddle, or Glitch. Glitch es probablemente el mejor para este ejemplo, porque permite cargar propiedades como imágenes, mientras que algunas de las otras herramientas no lo hacen.
  2. +
  3. Escribe una publicación solicitando evaluación y/o ayuda en el foro MDN Discourse forum. Agrega la etiqueta "aprendizaje" a tu publicación para que podamos encontrarla más fácilmente. Tu publicación debe incluir: +
      +
    • Un título descriptivo como "Evaluación para página de bienvenida de Mozilla".
    • +
    • Detalles de lo que quiera que hagamos, por ejemplo, lo que ya has intentado, si estás atascado y necesitas ayuda.
    • +
    • Un enlace al ejemplo que deseas evaluar o en el que necesitas ayuda, en un editor en línea. Ésta es una buena práctica: es muy difícil ayudar a alguien con un problema de codificación si no puede ver su código.
    • +
    • Un enlace a la página de evaluación actual, para que podamos encontrar la pregunta con la que desea ayuda.
    • +
    +
  4. +
+ +

{{PreviousMenu("Learn/HTML/Multimedia_and_embedding/Responsive_images", "Learn/HTML/Multimedia_and_embedding")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html b/files/es/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html new file mode 100644 index 0000000000..67b01247a4 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html @@ -0,0 +1,371 @@ +--- +title: Desde object hasta iframe - otras tecnologías de incrustación +slug: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies +translation_of: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}
+ +

Ahora ya deberías estar acostumbrado a integrar cosas en tus páginas web, incluyendo imágenes, video y audio. En este punto nos gustaría que des algo así como un paso al costado, prestando atención a elementos que te permiten integrar una amplia variedad de tipos de contenido en tus páginas web: los elementos {{htmlelement("iframe")}}, {{htmlelement("embed")}} y {{htmlelement("object")}}. Los <iframe>s son para incrustar otras páginas web, y los otros dos te permiten incrustar PDFs, SVG e incluso Flash — una tecnología que está en su camino de despedida, pero la cual seguirás viendo semi-regularmente.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, software básico instalado, conocimientos básicos de  manejo de archivos, familiaridad con los fundamentos de HTML (visto en Iniciando en HTML) y los artículos previos en este modulo.
Objetivo:To learn how to embed items into web pages using {{htmlelement("object")}}, {{htmlelement("embed")}}, and {{htmlelement("iframe")}}, like Flash movies and other webpages.
+ +

Enlace a la sección: Una breve historia de incrustación

+ +

Hace mucho tiempo en la Web, era popular usar marcos (frames) para crear sitios web, pequeñas partes de un sitio web almacenadas en páginas HTML individuales. Estos estaban incrustados en un documento maestro llamado conjunto de marcos (frameset), que le permitía especificar el área en la pantalla que ocupaba cada cuadro, como el tamaño de las columnas y las filas de una tabla. Estos fueron considerados el colmo del frescor a mediados y finales de los 90, y había evidencia de que tener una página web dividida en trozos más pequeños como este era mejor para velocidades de descarga, especialmente notable con conexiones de red tan lentas en ese momento. Sin embargo, tuvieron muchos problemas, que superaron con creces cualquier aspecto positivo ya que las velocidades de red se hicieron más rápidas, por lo que ya no se ve que se usen.

+ +

Poco tiempo después (finales de los 90, principios de 2000), las tecnologías de complementos se volvieron muy populares, como los Applets de Java y Flash . Esto permitió a los desarrolladores web incorporar contenido enriquecido en páginas web como videos y animaciones, que simplemente no estaban disponibles solo a través de HTML. La incrustación de estas tecnologías se logró a través de elementos como <object> y el menos utilizado <embed> , que fueron muy útiles en ese momento. Desde entonces, pasaron de moda debido a muchos problemas, incluidos el acceso, la seguridad, el tamaño del archivo y entre otros; en la actualidad, la mayoría de los dispositivos móviles ya no son compatibles con estos complementos, y el soporte de escritorio está en camino de desaparecer.

+ +

Finalmente, apareció el elemento <iframe> (junto con otras formas de incrustación de contenido, como <canvas> , <video> , etc.). Esto proporciona una forma de insertar un documento web entero dentro de otro, como si fuera un <img> u otro elemento similar, y  asi es como se usa en la actualidad.

+ +

Con la lección de historia fuera del camino, sigamos y veamos cómo usar algunos de estos.

+ +

Aprendizaje activo: usos de incrustación clásicos

+ +

En este artículo vamos a ir directamente a una sección de aprendizaje activo, para darle una idea real de la utilidad de las tecnologías de inclusión. El mundo en línea está muy familiarizado con Youtube, pero muchas personas no conocen algunas de las comodidades para compartir que tiene disponibles. Veamos cómo Youtube nos permite insertar un video en cualquier página que nos guste usando un <iframe> .

+ +
    +
  1. Primero, ve a Youtube y encuentra el video que te gusta.
  2. +
  3. Debajo del video, encontrará un botón Compartir : seleccionelo para mostrar las opciones para compartir.
  4. +
  5. Seleccione el botón Insertar y recibirá un código <iframe> - copielo.
  6. +
  7. Insértelo en el cuadro de entrada a continuación, y vea cuál es el resultado en la salida .
  8. +
+ +

Para obtener puntos de bonificación, también puede intentar insertar un mapa de Google en el ejemplo:

+ +
    +
  1. Ve a Google Maps y encuentra un mapa que te guste.
  2. +
  3. Haga clic en el "Menú Hamburger" (tres líneas horizontales) en la esquina superior izquierda de la IU.
  4. +
  5. Seleccione la opción Compartir o Insertar mapa .
  6. +
  7. Seleccione la opción Insertar mapa, que le dará un código <iframe> - copielo.
  8. +
  9. Insértelo en el cuadro de entrada a continuación, y vea cuál es el resultado en la salida .
  10. +
+ +

Si comete un error, siempre puede restablecerlo usando el botón Restablecer . Si realmente te quedas atascado, presiona el botón Mostrar solución para ver una respuesta.

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 600, "", "", "hide-codepen-jsfiddle") }}

+ +

Iframes en detalle

+ +

Entonces, fue fácil y divertido ¿verdad? Los elementos {{htmlelement("iframe")}} están diseñados para permitirte incrustar documentos web en el documento actual.  Esto es excelente para incorporar contenido de terceros en tu sitio web sobre el que no tengas control directo y no quieras tener que implementar tu propia versión — como vídeo de porveedeores de vídeo en línea, sistemas de comentarios como Disqus, mapas de proveedores de mapas en línea, banners publicitarios, etc. Los ejemplos editables que has estado usando a través de este curso se implementan usando <iframe>s.

+ +

Hay algunos serios  {{anch("Security concerns")}} a considerar con <iframe>s, también se discute a continuación, pero esto no significa que debas dejar de usarlos en tus sitios web — solo requiere un poco de conocimiento y pensar cuidadosamente. Vamos a explorar el código con un poco más de detalle. Supongamos que quieres incluir el glosario de MDN en una de tus páginas web — podrías intentar algo como esto:

+ +
<iframe src="https://developer.mozilla.org/en-US/docs/Glossary"
+        width="100%" height="500" frameborder="0"
+        allowfullscreen sandbox>
+  <p> <a href="https://developer.mozilla.org/en-US/docs/Glossary">
+    Fallback link for browsers that don't support iframes
+  </a> </p>
+</iframe>
+ +

Este ejemplo incluye los elementos básicos necesarios para usar un  <iframe>:

+ +
+
{{htmlattrxref('allowfullscreen','iframe')}}
+
Si está configurado, el  <iframe> se puede colocar en modo pantalla completa usando el  Full Screen API (El uso del API está fuera del alcance de este artículo.)
+
{{htmlattrxref('frameborder','iframe')}}
+
Si se establece en 1, esto le indica al navegador que dibuje un borde entre este marco y otros marcos, que es el comportamiento predeterminado. 0 elimina el borde. Usar esto ya no es realmente recomendable, ya que el mismo efecto se puede lograr mejor usando{{cssxref('border')}}: none; en tu {{Glossary('CSS')}}.
+
{{htmlattrxref('src','iframe')}}
+
Este atributo, como con {{htmlelement("video")}}/{{htmlelement("img")}},contiene una ruta que apunta a la URL del documento que se va a incrustar.
+
{{htmlattrxref('width','iframe')}} and {{htmlattrxref('height','iframe')}}
+
Estos atributos especifican el ancho y la altura (width y height) que quieres que tenga el iframe.
+
Contenido de reserva
+
De la misma manera que otros elementos similares {{htmlelement("video")}}, puedes incluir contenido alternativo entre las etiquetas de apertura y cierre <iframe></iframe> que aparecerán si el navegador no admite el  <iframe>. En este caso hemos incluido un enlace a la página. Es poco probable que encuentres algún navegador que no admita <iframe>s en estos días.
+
{{htmlattrxref('sandbox','iframe')}}
+
Este atributo, que funciona en navegadores un poco más modernos que el resto de la funciones de <iframe> (por ejemplo IE 10 y superior) solicita una mayor configuración de seguridad; bueno, hablaremos más sobre esto en la siguiente sección.
+
+ +
+

Nota: Para mejorar la velocidad, es una buena idea establecer el atributo src de iframes con  JavaScript después de que se cargue el contenido principal. Esto hace que tu página pueda utilizarse antes y disminuye el tiempo de carga de tu página principal (an important {{Glossary("SEO")}}.)

+
+ +

Con respecto  a la seguridad

+ +

Arriba mencionamos nuestra preocupación por la seguridad — vamos a entrar en esto con un poco más de detalle ahora. No esperamos que comprendas todo este contenido perfectametne a la primera. Solo queremos informarte sobre esta preocupación y proporcionarte una referencia a la que volver a medida que tengas más experiencia y comiences  a considerar el uso de  <iframe>s en tu trabajo y  en tus experimentos.además, no es necesario tener miedo y no usar  <iframe>s — iframes, solo debes tener cuidado. Sigue leyendo...

+ +

Los creadores de navegadores y los desarrolladores web han aprendido por las malas que los iframes son un objetivo común (término oficial: vector de ataque) para los "malos" de la Web (a menudo denominados hackers,o más exactamente, crackers) para atacar si están tratando de modificar maliciosamente tu página web, o engañar a las personas para que hagan algo que no quieren hacer, como revelar información confidencial como nombre de usuario o contraseña. Debido a esto, los ingenieros de especificaciones y los desarrolladores de navegadores han desarrollado varios mecanismos  para hacer que los <iframe>s sean más seguros, y también hay mejores prácticas a considerar — cubriremos algunas de estas a continuación.

+ +
+

{{interwiki('wikipedia','Clickjacking')}} es un tipo de ataque de iframe común en el que los piratas informáticos incrustan un iframe invisible en tu documento (o incrustan tu documento en su propio sitio web malicioso) y lo utilizan para capturar las interacciones de los ususarios. Esta es una forma común de engañar a los usuarios o robar datos sensibles.

+
+ +

Primero un ejemplo rápido — intenta cargar el ejemplo anterior que mostramos arriba en tu navegador — puedes encontrarlo en  Github (ver el código fuente ) Tu no verás nada en tu navegador, pero si miras en la Consola en las herramientas de desarrollador de tu navegador,  tú verás un mensaje diciendote porque.En Firefox, te dirá Load denied by X-Frame-Options: https://developer.mozilla.org/en-US/docs/Glossary does not permit framing. Esto es porque los desarrolladores que construyeron MDN han incluido una configuración en el servidor que almacena la página web que impide que sean incrustados dentro de  <iframe>s (ver {{anch("Configure CSP directives")}}, abajo.) Esto tiene sentido— una página completa de MDN no tiene sentido estar incrustada en otras páginas, a menos que tu quieras hacer algo como incrustarlas en tu sitio web y reclamarlas como propias  — o intentar robar datos via clickjacking, los cuales ambos son cosas realmente malas. Además de que si todo el mundo comienza a hacerlo, todo el ancho de banda adicional podría costarle mucho dinero a Mozzilla.

+ +

Solo incrusta cuando sea necesario

+ +

Algunas veces tiene sentido embeber contenido de terceros— como vídeos de youtube y mapas — pero puedes ahorrarte muchos dolores de cabeza si tu solo embebes contenido de terceros solo cuando es necesario. Una buena regla de oro para la seguridad web es "Nunca puedes ser demasiado cauteloso. Si lo hizo, verifíquelo de todos modos. Si alguien más lo hizo, asuma que es peligroso hasta que se demuestre lo contrario".

+ +

Además de la seguridad, debes ser consciente de los temas de propiedad intelectual. La mayoría del contenido tiene derechos de autor, en línea y fuera de línea, incluso contenido que no te esperas(por ejemplo, la mayoría de las imágenes en Wikimedia Commons). Nunca muestres en tu pagina contenido a menos que te pertenezca o que el dueño te haya dado por escrito su permiso inequívoco. Las penalidades por derechos de autor son severas. De nuevo, tu nunca puedes ser demasiado cauteloso. 

+ +

Si el contenido es licenciado, debes obedecer los terminos de la licencia. Por ejemplo, el contenido en MDN es licenciado bajo CC-BY-SA. Esto significa, que tu debes darnos credito apropiadamente  cuando tu citas nuestro contenido, aun si tu haces cambios substanciales.

+ +

Usa HTTPS

+ +

{{Glossary("HTTPS")}} es la versión encriptada de {{Glossary("HTTP")}}. Deberias cumplir con tu página web usando HTTPS siempre que sea posible:

+ +
    +
  1. HTTPS reduce la oportunidad de que contenido remoto haya sido manipulado en el tránsito.
  2. +
  3. HTTPS previene que el contenido embebido acceda al documento padre y viceversa. 
  4. +
+ +

Usar HTTPS requiere un certificado de seguridad, el cual puede ser costoso (Aunque Let's Encrypt hace las cosas más faciles) — si tu no puedes tener uno, tu debes servir tu documento padre con HTTP. Sin embargo, debido al segundo beneficio de HTTPS expuesto arriba, no importa cual sea el costo tu nunca debes embeber contenido de terceros con HTTP. (En el mejor de los casos, el navegador de tus usuarios les dará una advertencia). Todas las empresas con buena reputación que hacen contenido para embeber via <iframe> lo harán  disponible via HTTPS — mira la URLs dentro del <iframe> atributo src cuando tu estes embebiendo contenido desde Google Maps o Youtube, por ejemplo.

+ +
+

Note: Github pages permite que el contenido sea servido via HTTPS  por defecto, asi que es util para hospedar tu contenido. Si estás usando un hosting diferente y no estás seguro, pregunta a tu proveedor de hosting acerca del tema .

+
+ +

Siempre usa el atributo sandbox

+ +

You want to give attackers as little power as you can to do bad things on your website, therefore you should give embedded content only the permissions needed for doing its job. Of course, this applies to your own content, too. un contenedor para codigo que puedes usar apropiadamente — o para probar — but can't cause any harm to the rest of the codebase (either accidental or malicious) is called a sandbox.

+ +

Unsandboxed content can do way too much (executing JavaScript, submitting forms, popup windows, etc.) By default you should impose all available restrictions by using the sandbox attribute with no parameters, as shown in our previous example.

+ +

If absolutely required, you can add permissions back one by one (inside the sandbox="" attribute value) — see the {{htmlattrxref('sandbox','iframe')}} reference entry for all the available options. One important note is that you should never add both allow-scripts and allow-same-origin to your sandbox attribute — in that case the embedded content could bypass the same origin security policy that stops sites from executing scripts, and use JavaScript to turn off sandboxing altogether.

+ +
+

Note: Sandboxing provides no protection if attackers can fool people into visiting malicious content directly (outside an iframe). If there's any chance that certain content may be malicious (e.g., user-generated content), please serve it from a different {{glossary("domain")}} to your main site.

+
+ +

Configure CSP directives

+ +

{{Glossary("CSP")}} stands for content security policy, and provides a set of HTTP Headers (metadata sent along with your web pages when they are served from a web server) designed to improve the security of your HTML document. When it comes to securing <iframe>s, you can configure your server to send an appropriate X-Frame-Options  header. This can prevent other websites from embedding your content in their webpages (which would enable {{interwiki('wikipedia','clickjacking')}} and a host of other attacks), which is exactly what the MDN developers have done, as we saw earlier on.

+ +
+

Note: You can read Frederik Braun's post On the X-Frame-Options Security Header for more background information on this topic. Obviously, it's rather out of scope for a full explanation in this article.

+
+ +

The <embed> and <object> elements

+ +

The {{htmlelement("embed")}} and {{htmlelement("object")}} elements serve a different function to {{htmlelement("iframe")}} — these elements are general purpose embedding tools for embedding multiple types of external content, which include plugin technologies like Java Applets and Flash, PDF (which can be shown in a browser with a PDF plugin), and even content like videos, SVG and images!

+ +
+

Note: A plugin is software that provides access to content the browser cannot read natively.

+
+ +

However, you are unlikely to use these elements very much — Applets haven't been used for years, Flash is no longer very popular, due to a number of reasons (see {{anch("The case against plugins")}}, below), PDFs tend to be be better linked to than embedded, and other content such as images and video have much better, easier elements to handle those. Plugins and these embedding methods are really a legacy technology, and we are mainly mentioning them in case you come across them in certain circumstances like intranets, or enterprise projects.

+ +

If you find yourself needing to embed plugin content, this is the kind of information you'll need, at a minimum:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{htmlelement("embed")}}{{htmlelement("object")}}
{{glossary("URL")}} of the embedded content{{htmlattrxref('src','embed')}}{{htmlattrxref('data','object')}}
accurate {{glossary("MIME type", 'media type')}} of the embedded content{{htmlattrxref('type','embed')}}{{htmlattrxref('type','object')}}
height and width (in CSS pixels) of the box controlled by the plugin{{htmlattrxref('height','embed')}}
+ {{htmlattrxref('width','embed')}}
{{htmlattrxref('height','object')}}
+ {{htmlattrxref('width','object')}}
names and values, to feed the plugin as parametersad hoc attributes with those names and valuessingle-tag {{htmlelement("param")}} elements, contained within <object>
independent HTML content as fallback for an unavailable resourcenot supported (<noembed> is obsolete)contained within <object>, after <param> elements
+ +
+

Note: <object> requires a data attribute, a type attribute, or both. If you use both, you may also use the {{htmlattrxref('typemustmatch','object')}} attribute (only implemented in Firefox, as of this writing). typemustmatch keeps the embedded file from running unless the type attribute provides the correct media type. typemustmatch can therefore confer significant security benefits when you're embedding content from a different {{glossary("origin")}} (it can keep attackers from running arbitrary scripts through the plugin).

+
+ +

Here's an example that uses the {{htmlelement("embed")}} element to embed a Flash movie (see this live on Github, and check the source code too):

+ +
<embed src="whoosh.swf" quality="medium"
+       bgcolor="#ffffff" width="550" height="400"
+       name="whoosh" align="middle" allowScriptAccess="sameDomain"
+       allowFullScreen="false" type="application/x-shockwave-flash"
+       pluginspage="http://www.macromedia.com/go/getflashplayer">
+ +

Pretty horrible, isn't it. The HTML generated by the Adobe Flash tool tended to be even worse, using an <object> element with an <embed> element embedded in it, to cover all bases (check out an example.) Flash was even used successfully as fallback content for HTML5 video, for a time, but this is increasingly being seen as not necessary.

+ +

Now let's look at an <object> example that embeds a PDF into a page (see the live example and the source code):

+ +
<object data="mypdf.pdf" type="application/pdf"
+        width="800" height="1200" typemustmatch>
+  <p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p>
+</object>
+ +

PDFs were a necessary stepping stone between paper and digital, but they pose many accessibility challenges and can be hard to read on small screens. They do still tend to be popular in some circles, but it is much better to link to them so they can be downloaded or read on a separate page, rather than embedding them in a webpage.

+ +

The case against plugins

+ +

Once upon a time, plugins were indispensable on the Web. Remember the days when you had to install Adobe Flash Player just to watch a movie online? And then you constantly got annoying alerts about updating Flash Player and your Java Runtime Environment. Web technologies have since grown much more robust, and those days are over. For most applications, it's time to stop delivering content that depends on plugins, and start taking advantage of Web technologies instead.

+ + + +

So what should you do? If you need interactivity, HTML and {{glossary("JavaScript")}} can readily get the job done for you with no need for Java applets or outdated ActiveX/BHO technology. Instead of relying on Adobe Flash, you can use HTML5 video for your media needs, SVG for vector graphics, and Canvas for complex images and animations. Peter Elst was already writing some years ago that Adobe Flash is rarely the right tool for the job, except for specialized gaming and business applications. As for ActiveX, even Microsoft's {{glossary("Microsoft Edge","Edge")}} browser no longer supports it.

+ +

Summary

+ +

The topic of embedding other content in web documents can quickly become very complex, so in this article we've tried to introduce it in a simple, familiar way that will immediately seem relevant, while still hinting at some of the more advanced features of the involved technologies. To start with, you are unlikely to use embedding for much beyond including third party content like maps and videos on your pages. As you become more experienced however, you are likely to start finding more uses for them.

+ +

There are many other technologies that involve embedding external content besides the ones we discussed here. We saw some in earlier articles, such as {{htmlelement("video")}}, {{htmlelement("audio")}}, and {{htmlelement("img")}}, but there are others to discover, such as {{htmlelement("canvas")}} for JavaScript-generated 2D and 3D graphics, and {{htmlelement("svg")}} for embedding vector graphics. We'll look at SVG in the next article of the module.

+ +

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}

+ +

In this module

+ + diff --git a/files/es/learn/html/multimedia_and_embedding/responsive_images/index.html b/files/es/learn/html/multimedia_and_embedding/responsive_images/index.html new file mode 100644 index 0000000000..daa97085e9 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/responsive_images/index.html @@ -0,0 +1,265 @@ +--- +title: Imágenes adaptables +slug: Learn/HTML/Multimedia_and_embedding/Responsive_images +translation_of: Learn/HTML/Multimedia_and_embedding/Responsive_images +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page", "Learn/HTML/Multimedia_and_embedding")}}
+ +
+

En este artículo, aprenderemos sobre el concepto de imágenes adaptables — imágenes que funcionan bien en dispositivos con una amplia diferencia de tamaño de pantallas, resoluciones y otras tantas características — y observar qué herramientas proporciona HTML para ayudar a implementarlas. Esto ayuda a mejorar el rendimiento en diferentes dispositivos.

+ +

Las imágenes adaptables son solo una parte del diseño web responsivo, un tema que aprenderás próximamente en nuestro tutorial de CSS.

+
+ + + + + + + + + + + + +
Prerrequisitos:Deberías tener un conocimiento básico de HTML y cómo agregar imágenes estáticas a un sitio web.
 Objetivo: Aprende a usar características como {{htmlattrxref("srcset", "img")}} y el elemento {{htmlelement("picture")}} para implementar soluciones de imágenes adaptables a sitios web.
+ +

¿Por qué imágenes adaptables?

+ +

Examinemos un escenario típico. Un sitio web típico puede contener una imagen de encabezado y algunas imágenes de contenido debajo del encabezado. Es probable que la imagen del encabezado abarque todo el ancho del encabezado y la imagen del contenido quepa en algún lugar dentro de la columna de contenido. He aquí un ejemplo sencillo:

+ +

Our example site as viewed on a wide screen - here the first image works ok, as it is big enough to see the detail in the center.

+ +

Esto funciona bien en un dispositivo de pantalla ancha, como una computadora portatil o de escritorio (puedes ver el ejemplo en vivo y encontrar el código fuente en Github.) No hablaremos mucho del CSS en esta lección, excepto para decir que:

+ + + +

Sin embargo, surgen problemas cuando comienza a ver el sitio en un dispositivo de pantalla estrecha — el encabezado de abajo está bien, pero empieza a ocupar gran parte de la altura de la pantalla de un dispositivo móvil. ¡A este tamaño es difícil ver a las personas que aparecen en la foto!

+ +

Our example site as viewed on a narrow screen; the first image has shrunk to the point where it is hard to make out the detail on it.

+ +

Una mejora sería mostrar una versión recortada de la imagen que muestra los detalles importantes de la imagen cuando el sitio se ve en una pantalla estrecha. Se podría mostrar una segunda imagen recortada para un dispositivo de pantalla de ancho medio, como una tableta. A esto se le conoce comúnmente como el problema de cambio de resolución.

+ +

Además, no es necesario incrustar imágenes más grandes en la página si se está viendo en una pantalla móvil. Y, a la inversa, una imagen rasterizada pequeña comienza a verse más pixelada cuando se muestra mayor que su tamaño original (una imagen rasterizada es un conjunto determinado de píxeles de ancho y de alto, como vimos cuando vimos los gráficos vectoriales). Esto se denomina problema de cambio de resolución.

+ +

Por el contrario, no es necesario mostrar una imagen grande en una pantalla significativamente más pequeña que el tamaño para el que fue diseñada. Hacerlo puede desperdiciar ancho de banda; en particular, los usuarios de dispositivos móviles no quieren desperdiciar ancho de banda descargando una imagen grande destinada al escritorio, cuando una imagen pequeña sería suficiente para su dispositivo. Idealmente, tendría varias resoluciones disponibles y serviría el tamaño apropiado según el dispositivo que acceda a los datos en el sitio web.

+ +

Para hacer las cosas más complicadas, algunos dispositivos tienen pantallas de alta resolución que necesitan imágenes más grandes de las que se espera que luzcan bien. Esto es, básicamente, el mismo problema, pero en un contexto ligeramente diferente.

+ +

Podrías pensar que las imágenes vectoriales resolverían estos problemas, y lo hacen hasta cierto punto: son pequeñas en tamaño de archivo y escalan bien, y deberías usarlos siempre que sea posible. Sin embargo, no son adecuados para todos tipos de imágenes. Si bien son geniales para gráficos simples, patrones, elementos de interfaz, etc., es muy complejo crear una imagen basada en vectores con la cantidad de detalles que encontrarías, por ejemplo, en una foto. Formatos de imágenes rasterizadas como JPEG son más adecuados para el tipo de imágenes que vemos en el ejemplo anterior.

+ +

Este tipo de problemas no existían cuando la web se creó por primera vez, a principios y mediados de los noventa — en ese entonces, los únicos dispositivos disponibles para navegar por la web eran los ordenadores de escritorio y laptops, por lo que los desarrolladores e ingenieros que programaban los navegadores ni siquiera pensaban en implementar estas soluciones. Las tecnologías de imagen adaptable se implementaron recientemente para resolver los problemas descritos anteriormente al permitirle ofrecer al navegador varias versiones de imágenes (en diferentes archivos), ya sea que muestren lo mismo pero contengan diferentes números de píxeles (cambio de resolución), o diferentes imágenes adecuadas para diferentes asignaciones de espacio (dirección de arte).

+ +
+

Nota: Las nuevas características discutidas en este artículo — {{htmlattrxref("srcset", "img")}}/{{htmlattrxref("sizes", "img")}}/{{htmlelement("picture")}} —son compatibles con las versiones de lanzamiento de los navegadores de escritorio y móviles modernos (incluido el navegador Edge de Microsoft, aunque no Internet Explorer).

+
+ +

¿Cómo se crean las imágenes adaptables?

+ +

En esta sección, veremos los dos problemas ilustrados anteriormente y mostraremos cómo solucionarlos usando las características de imágenes adaptables con HTML. Debe tener en cuenta que nos centraremos en el elemento HTML {{htmlelement("img")}} para esta sección, tal como se muestra en el área de contenido del ejemplo anterior —  la imagen en el encabezado del sitio es solo de decoración y, por lo tanto, implementado usando imágenes de fondo con CSS. Se puede decir que CSS posee mejores herramientas para el diseño adaptable que HTML, y hablaremos sobre ellas en nuestro módulo CSS.  

+ +

Cambio de resolución: Diferentes tamaños

+ +

Entonces, ¿qué queremos solucionar con el cambio de resolución? Queremos mostrar la misma imagen, más grande o más pequeña dependiendo del dispositivo — Esta es la situación que tenemos en la segunda imagen de nuestro ejemplo. El elemento estándar {{htmlelement("img")}} tradicionalmente solo permite apuntar el navegador a un solo archivo fuente:

+ +
<img src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
+ +

Sin embargo, podemos utilizar dos nuevos atributos — {{htmlattrxref("srcset", "img")}} y {{htmlattrxref("sizes", "img")}} — para proporcionar varias imágenes de origen adicionales junto con sugerencias para ayudar al navegador a elegir el correcto. Puede ver el ejemplo responsive.html en Github (vea también el código fuente):

+ +
<img srcset="elva-fairy-320w.jpg 320w,
+             elva-fairy-480w.jpg 480w,
+             elva-fairy-800w.jpg 800w"
+     sizes="(max-width: 320px) 280px,
+            (max-width: 480px) 440px,
+            800px"
+     src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
+ +

Los atributos srcsetsizes parecen complicados, pero resultan más fáciles de entender si los formatea como se muestra arriba, con valores diferentes para el atributo en cada línea. Cada valor contiene una lista separada por coma, y cada parte de la lista está compuesta por tres sub-partes. Repasemos ahora el contenido de cada uno:

+ +

srcset define el conjunto de imágenes que el navegador podrá elegir, y el tamaño de cada imagen. Cada conjunto de información de imagen está separado del anterior por una coma. Para cada uno, escribimos:

+ +
    +
  1. Un nombre de archivo de imagen (elva-fairy-480w.jpg)
  2. +
  3. Un espacio.
  4. +
  5. El ancho intrínseco de la imagen en píxeles (480w): tenga en cuenta que esto usa la unidad w, no px como cabría esperar. Este es el tamaño real de la imagen, que se puede encontrar inspeccionando el archivo de imagen en su computadora (por ejemplo, en una Mac puede seleccionar la imagen en Finder y presionar Cmd + I para que aparezca la pantalla de información).
  6. +
+ +

sizes define un conjunto de condiciones de medios (por ejemplo, anchos de pantalla) e indica qué tamaño de imagen sería mejor elegir cuando se cumplen ciertas condiciones de medios  — estas son las sugerencias de las que hablamos anterriormente. En este caso, antes de cada coma escribimos:

+ +
    +
  1. Una condición de medios ((max-width: 600px)): aprenderá más sobre esto en el tema CSS, pero por ahora digamos que una condición de medios describe un posible estado en el que puede estar la pantalla. En este caso, estamos diciendo "cuando el ancho de la ventana gráfica es de 600 píxeles o menos".
  2. +
  3. Un espacio.
  4. +
  5. El ancho de la ranura que la imagen llenará cuando la condición de medios sea verdadera (440px.)
  6. +
+ +
+

Nota: Para el ancho de la ranura, debe indicar una longitud absoluta (px, em) o relativa (como un porcentaje.) Usted debe haber advertido que el ancho de la última ranura no tiene condición de medios (esta es la opción por defecto que se elige cuando ninguna de las condiciones de medios se cumplen). El navegador ignora todo lo posterior a la primera condición coincidente, por eso sea cuidadoso con el orden de las condiciones de medios.

+
+ +

Entonces, con estos atributos establecidos, el navegador:

+ +
    +
  1. Verificará el ancho del dispositivo.
  2. +
  3. Resolverá qué condición de medios en la lista sizes es la primera que se cumple.
  4. +
  5. Verificará la medida de la ranura dada a esa consulta de medios.
  6. +
  7. Cargará la imagen referenciada en la lista srcset con coincidencia más cercana a la medida de la ranura.
  8. +
+ +

¡Y eso es todo! Hasta este punto, si un navegador compatible con un ancho de ventana de 480px carga la página, la condición de medios (max-width: 480px) se cumplirá, por lo que la ranura de 440px será elegida y se cargará el archivo de imagen elva-fairy-480w.jpg, ya que el ancho inherente (480w) es el más cercano a 440px. La imagen de 800px tiene 128KB en disco mientras que la versión de 480px tiene solo 63KB — un ahorro de 65KB. Ahora imagine si esta fuera una página que tuviera muchas imágenes. Usar esta técnica puede ahorrarle a los usuarios de dispositivos móviles mucho ancho de banda.

+ +
+

Nota: Al probar esto con un navegador de escritorio, si el navegador no carga las imágenes más estrechas cuando tiene su ventana configurada en el ancho más estrecho, eche un vistazo a cuál es la ventana gráfica (puede aproximarla yendo a la Consola JavaScript del navegador y escribiendo document.querySelector('html').clientWidth). Los diferentes navegadores tienen tamaños mínimos a los que te permitirán reducir el ancho de la ventana y pueden ser más anchos de lo que piensas. Al probarlo con un navegador móvil, puede usar herramientas como la página de depuración de Firefox about:debugging para inspeccionar la página cargada en el dispositivo móvil usando las herramientas de desarrollo de escritorio. Para ver qué imágenes se cargaron, puede usar la pestaña Monitor de red en las herramientas del desarrollador de Firefox.

+
+ +

Los navegadores más antiguos que no soportan estas características solo las ignorarán y seguirán adelante con la carga de la imagen referenciada en el atributo {{htmlattrxref("src", "img")}} como lo hacen habitualmente.

+ +
+

Nota: En el {{htmlelement("head")}} del documento usted hallará la línea <meta name="viewport" content="width=device-width">: esto fuerza a los dispositivos móviles a adoptar su ancho real de ventana para cargar las páginas web (algunos navegadores móviles mienten sobre el ancho de su ventana gráfica y, en su lugar, cargan páginas con un ancho de ventana más grande y luego reducen la página cargada, lo que no es muy útil para imágenes o diseño receptivos).

+
+ +

Useful developer tools

+ +

There are some useful developer tools in browsers to help with working out the necessary slot widths, etc, that you need to use. When I was working them out, I first loaded up the non-responsive version of my example (not-responsive.html), then went into Responsive Design View (Tools > Web Developer > Responsive Design View), which allows you to look at your web page layouts as if they were being viewed through a variety of different device screen sizes.

+ +

I set the viewport width to 320px then 480px; for each one I went into the DOM Inspector, clicked on the {{htmlelement("img")}} element we are interested in, then looked at its size in the Box Model view tab on the right hand side of the display. This should give you the inherent image widths you need.

+ +

A screenshot of the firefox devtools with an image element highlighted in the dom, showing its dimensions as 440 by 293 pixels.

+ +

Next, you can check whether the srcset is working by setting the viewport width to what you want (set it to a narrow width, for example), opening the Network Inspector (Tools > Web Developer > Network), then reloading the page. This should give you a list of the assets that were downloaded to make up the webpage, and here you can check which image file was chosen for download.

+ +

a screenshot of the network inspector in firefox devtools, showing that the HTML for the page has been downloaded, along with three images, which include the two 800 wide versions of the responsive images

+ +

Resolution switching: Same size, different resolutions

+ +

If you're supporting multiple display resolutions, but everyone sees your image at the same real-world size on the screen, you can allow the browser to choose an appropriate resolution image by using srcset with x-descriptors and without sizes — a somewhat easier syntax! You can find an example of what this looks like in srcset-resolutions.html (see also the source code):

+ +
<img srcset="elva-fairy-320w.jpg,
+             elva-fairy-480w.jpg 1.5x,
+             elva-fairy-640w.jpg 2x"
+     src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
+
+ +

A picture of a little girl dressed up as a fairy, with an old camera film effect applied to the imageIn this example, the following CSS is applied to the image so that it will have a width of 320 pixels on the screen (also called CSS pixels):

+ +
img {
+  width: 320px;
+}
+ +

In this case, sizes is not needed — the browser simply works out what resolution the display is that it is being shown on, and serves the most appropriate image referenced in the srcset. So if the device accessing the page has a standard/low resolution display, with one device pixel representing each CSS pixel, the elva-fairy-320w.jpg image will be loaded (the 1x is implied, so you don't need to include it.) If the device has a high resolution of two device pixels per CSS pixel or more, the elva-fairy-640w.jpg image will be loaded. The 640px image is 93KB, whereas the 320px image is only 39KB.

+ +

Art direction

+ +

To recap, the art direction problem involves wanting to change the image displayed to suit different image display sizes. For example, if a large landscape shot with a person in the middle is shown on a website when viewed on a desktop browser, then shrunk down when the website is viewed on a mobile browser, it will look bad as the person will be really tiny and hard to see. It would probably be better to show a smaller, portrait image on mobile, which shows the person zoomed in. The {{htmlelement("picture")}} element allows us to implement just this kind of solution.

+ +

Returning to our original not-responsive.html example, we have an image that badly needs art direction:

+ +
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
+ +

Let's fix this, with {{htmlelement("picture")}}! Like <video> and <audio>, The <picture> element is a wrapper containing several {{htmlelement("source")}} elements that provide several different sources for the browser to choose between, followed by the all-important {{htmlelement("img")}} element. The code in responsive.html looks like so:

+ +
<picture>
+  <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
+  <source media="(min-width: 800px)" srcset="elva-800w.jpg">
+  <img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
+</picture>
+
+ + + +

This code allows us to display a suitable image on both wide screen and narrow screen displays, as shown below:

+ +

Our example site as viewed on a wide screen - here the first image works ok, as it is big enough to see the detail in the center.Our example site as viewed on a narrow screen with the picture element used to switch the first image to a portrait close up of the detail, making it a lot more useful on a narrow screen

+ +
+

Note: You should use the media attribute only in art direction scenarios; when you do use media, don't also offer media conditions within the sizes attribute.

+
+ +

¿Por qué no podemos usar, simplemente, CSS o Javascript?

+ +

Cuando el navegador comienza a cargar una página, empieza a descargar (precargar) cualquier imagen before the main parser has started to load and interpret the page's CSS and JavaScript. This is a useful technique, which on average has shaved 20% off page load times. However, it is not helpful for responsive images, hence the need to implement solutions like srcset. You couldn't for example load the {{htmlelement("img")}} element, then detect the viewport width with JavaScript and dynamically change the source image to a smaller one if desired. By then, the original image would already have been loaded, and you would load the small image as well, which is even worse in responsive image terms.

+ + + +

Use modern image formats boldly

+ +

There are several exciting new image formats (such as WebP and JPEG-2000) that can maintain a low file size and high quality at the same time. However, browser support is spotty.

+ +

<picture> lets us continue catering to older browsers. You can supply MIME types inside type attributes so the browser can immediately reject unsupported file types:

+ +
<picture>
+  <source type="image/svg+xml" srcset="pyramid.svg">
+  <source type="image/webp" srcset="pyramid.webp">
+  <img src="pyramid.png" alt="regular pyramid built from four equilateral triangles">
+</picture>
+
+ + + +

Aprendizaje activo: Implementando sus propias imágenes adaptables

+ +

For this active learning, we're expecting you to be brave and go it alone ... mostly. We want you to implement your own suitable art directed narrow screen/wide screen shot using <picture>, and a resolution switching example that uses srcset.

+ +
    +
  1. Write some simple HTML to contain your code (use not-responsive.html as a starting point, if you like)
  2. +
  3. Find a nice wide screen landscape image with some kind of detail contained in it somewhere. Create a web-sized version of it using a graphics editor, then crop it to show a smaller part that zooms in on the detail, and create a second image (about 480px wide is good for this.)
  4. +
  5. Use the <picture> element to implement an art direction picture switcher!
  6. +
  7. Create multiple image files of different sizes, each showing the same picture.
  8. +
  9. Use srcset/size to create a resolution switcher example, either to serve the same size image at different resolutions, or different image sizes at different viewport widths.
  10. +
+ +
+

Note: Use the browser devtools to help work out what sizes you need, as mentioned above.

+
+ +

Resumen

+ +

That's a wrap for responsive images — we hope you enjoyed playing with these new techniques. As a recap, there are two distinct problems we've been discussing here:

+ + + +

This also draws to a close the entire Multimedia and embedding module! The only thing to do now before moving on is to try our multimedia assessment, and see how you get on. Have fun.

+ +

Vea también

+ + + +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page", "Learn/HTML/Multimedia_and_embedding")}}
+ +
+

En este módulo

+ + +
+ +

<hv-copy-modal></hv-copy-modal>

diff --git a/files/es/learn/html/multimedia_and_embedding/video_and_audio_content/index.html b/files/es/learn/html/multimedia_and_embedding/video_and_audio_content/index.html new file mode 100644 index 0000000000..e9b5571e23 --- /dev/null +++ b/files/es/learn/html/multimedia_and_embedding/video_and_audio_content/index.html @@ -0,0 +1,319 @@ +--- +title: Video and audio content +slug: Learn/HTML/Multimedia_and_embedding/Video_and_audio_content +translation_of: Learn/HTML/Multimedia_and_embedding/Video_and_audio_content +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Images_in_HTML", "Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding")}}
+ +

Ahora que estamos cómodos añadiendo imágenes simples a una página web, el siguiente paso será empezar a agregar reproductores de audio y video a tu documento HTML. En este artículo veremos cómo hacerlo con los elementos  {{htmlelement("video")}} y {{htmlelement("audio")}}; luego terminaremos viendo como agregar subtítulos a nuestros videos.

+ + + + + + + + + + + + +
Requisitos previos:Conocimientos básicos de computación, programas básicos instalados, conocimiento básico de trabajo con archivos, familiaridad con los fundamentos de HTML (como está cubierto en Empezando con HTML) e Imágenes en HTML.
Objetivo:Aprender como incrustar contenido de audio y video en una página web, y agregar subtítulos a los videos.
+ +

Audio y video en la web

+ +

Los desarrolladores web han querido usar audio y video en la web por mucho tiempo, desde comienzos del 2000 cuando empezamos a tener un ancho de banda suficientemente rápido para soportar cualquier tipo de video (los archivos de video son mucho más grandes que texto o imágenes). En los inicios, las tecnologías web nativas como HTML no tenían el soporte para incrustar audio y video en la Web, tecnologías privadas (o basadas en plugins) como Flash (y después, Silverlight) se convirtieron populares para manipular este tipo de contenido. Este tipo de tecnología funcionó bien, pero tenía ciertos problemas, incluídos el no trabajar bien con las características de HTML/CSS, problemas de seguridad y problemas de accesibilidad.

+ +

Una solución nativa podría resolver mucho de esto si es implementado correctamente. Afortunadamente, unos pocos años después la especificación {{glossary("HTML5")}} tenía tales características agregadas, con los elementos {{htmlelement("video")}} y {{htmlelement("audio")}}, y algo nuevo {{Glossary("JavaScript")}} {{Glossary("API","APIs")}} para controlar estos. No veremos Javascript aquí — solo los fundamentos básicos que se pueden lograr con HTML.

+ +

No te enseñaremos como crear archivos de audio y video — eso requiere un conocimiento completamente diferente. Por el contrario, te proporcionamos archivos de audio y video de muestra con códigos de ejemplo para que tu mismo experimentes, en caso de que no puedas conseguirlos por ti mismo.

+ +
+

Observación: Antes de empezar, también deberías saber que hay un puñado de OVPs (proveedores de video online) como YouTube, Dailymotion y Vimeo, y proveedores de audio como Soundcloud. Tales compañías ofrecen una conveniente fácil forma de hospedar y consumir videos, y que  no tienes que preocuparte sobre el enorme ancho de banda que se consume. Los OVPs normalmente usan código prefabricado para incrustar video/audio en tus sitios web; si  usas ese camino, puedes evitar algunas dificultates que discutimos en este artículo. Discutiremos este tipo de servicios un poco más en el siguiente artículo.

+
+ +

El elemento <video>

+ +

El elemento {{htmlelement("video")}} nos permite incrustar video fácilmente. Un ejemplo muy simple luce como lo siguiente:

+ +
<video src="rabbit320.webm" controls>
+  <p>Tu navegador no soporta HTML5 video. Aquí está el <a href="rabbit320.webm">enlace del video</a>.</p>
+</video>
+ +

Las características a notar son:

+ +
+
{{htmlattrxref("src","video")}}
+
De la misma manera que para el elemento {{htmlelement("img")}}, el atributo src (source) contiene una ruta al video que deseas incrustar. Funciona de la misma manera.
+
{{htmlattrxref("controls","video")}}
+
Los usuarios deben ser capaces de controlar la reproducción de video y audio (esto es especialmente crítico en personas que padecen  epilepsia). Se debe utilizar el atributo controls para incluir la interfaz de control del browser, o construir la nuestra utilizando la JavaScript API apropiada. Como mínimo la interfaz debe incluir una manera de empezar y terminar la reproducción, y ajustar el volumen.
+
El párrafo dentro de la etiqueta  <video>
+
Se lo llama fallback content (contenido de reserva) — y será mostrado si el browser desde el que se está accediendo a la página no soporta el elemento <video>, permitiéndonos proveer un fallback para browsers más antiguos. Puede ser de la manera que se quiera; en este caso proporcionamos un link directo al archivo de video, por lo que el usuario puede al menos acceder de alguna manera, independientemente del browser que esté usando.
+
+ +

El video incrustado se verá así:

+ +

A simple video player showing a video of a small white rabbit

+ +

Puedes probar el ejemplo aquí (también el código fuente).

+ +

Uso de formatos múltiples para mejorar la compatibilidad

+ +

Hay un problema con el ejemplo de arriba, que quizás  hayas notado si trataste de acceder al ejemplo en línea con un navegador como Safari o Internet Explorer. ¡El video no funciona! Esto es porque diferentes navegadores soportan diferentes formatos de video (y audio).

+ +

Contenidos de un archivo de medios

+ +

Repasemos la terminología rápidamente. Formatos como MP3, MP4 y WebM son llamados formatos contenedores. Estos contienen diferentes partes que componen toda la canción o video — como una pista de audio y una pista de video (en el caso del video), y metadatos para describir los contenidos que se presentan, qué codecs se usan para codificar sus canales, etcétera.

+ +

Un archivo WebM contiene una película que tiene una pista principal de video y otra pista con un ángulo alternativo, junto con audio en inglés y español, además de una pista con comentarios en inglés, lo que puede ser conceptualizado en el siguiente diagrama. También se incluyeron pistas de texto que contienen los subtítulos de la película en inglés, español y para el comentario.

+ +

+ +

Las pistas de audio y video dentro del contenedor mantienen los datos en un formato adecuado para el codec usado para codificar ese medio. Se usan diferentes formatos para pistas de audio versus de video. Cada pista de audio es codificada usando un codec de audio mientras que las pistas de video son codificadas (como probablemente ya has adivinado) usando un codec de video. Así como hemos hablado previamente, diferentes navegadores soportan diferentras formatos de audio y video, y diferentes formatos contenedores (como MP3, MP4 y WebM, que pueden contener diferentes tipos de video y audio).

+ +

Por ejemplo:

+ + + +

Un reproductor de audio tenderá a reproducir directamente un track de audio. Por ejemplo un archivo MP3 u Ogg. No necesitan contenedores.

+ +
+

Nota: No es tan simple como se ve en nuestra  tabla de compatibilidad de codecs audio-video. Además, muchos browsers de plataformas móviles pueden reproducir un formato no soportado entregándoselo al reproductor multimedia del sistema subyacente para que lo reproduzca. Pero esto servirá por ahora.

+
+ +

Los formatos anteriores existen para comprimir los archivos de audio y video volviéndolos manejables (el tamaño sin comprimir es muy grande). Los browsers contienen diferentes {{Glossary("Codec","Codecs")}}, como Vorbis o H.264, los cuales son usados para convertir el sonido y video comprimidos en binario y viceversa. Pero desafortunadamente, como indicamos antes, no todos los browsers soportan los mismos codecs, por lo tanto, habrá que proveer varios archivos para cada producción multimedia. Si te falta el codec correcto para decodificar el medio, simplemente no se reproducirá.

+ +
+

Nota: Debes estar preguntándote por qué sucede esto. El MP3 (para audio) y el MP4/H.264 (para video) son ampliamente compatibles y de buena calidad, sin embargo, también están patentados  — sus patentes cubren MP3 al menos hasta 2017 y a H.264 hasta 2027, lo que significa que los browsers que no tienen la patente tienen que pagar grandes sumas de dinero para soportar estos formatos. Además,  mucha gente no permite el software con restricciones, por estar a favor de formatos abiertos. Por todo esto es que tenemos que proveer múltiples formatos para los diferentes browsers.

+
+ +

Está bien, ¿pero cómo lo hacemos? Miremos el siguiente ejemplo actualizado (pruébalo en vivo aquí), o acá:

+ +
<video controls>
+  <source src="rabbit320.mp4" type="video/mp4">
+  <source src="rabbit320.webm" type="video/webm">
+  <p>Su navegador no soporta video HTML5. Aquí hay un <a href="rabbit320.mp4">enlace al video</a>.</p>
+</video>
+ +

Tomamos el atributo src del tag <video> y en su lugar incluimos elementos separados {{htmlelement("source")}} que apuntan a sus propias fuentes. En este caso el browser irá a los elementos <source> y reproducirá el primero de los elementos que el codec soporte. Incluir fuentes WebM y MP4 debería bastar para reproducir el video en la mayoría de los browsers en estos días.

+ +

Cada elemento  <source>  tambien tiene un atributo type . Esto es opcional, pero se recomienda que se incluyan, ya que contienen {{glossary("MIME type","MIME types")}} de los archivos de vídeo y los navegadores pueden leerlos y omitir inmediatamente los vídeos que no tienen. Si no estan incluidos, los navegadores cargarán e intentarán reproducir cada archivo hasta que encuentren uno que funcione, lo que llevará aún más tiempo y recursos.

+ +
+

Note: Nuestro articulo sobre soporte de formatos multimedia contiene algunos de los habituales {{glossary("MIME type","MIME types")}}.

+
+ +

Otras características de la etiqueta <video>

+ +

Hay varias otras características que puede incluir en un vídeo HTML5. Eche un vistazo a nuestro tercer ejemplo, a continuación.

+ +
<video controls width="400" height="400"
+       autoplay loop muted
+       poster="poster.png">
+  <source src="rabbit320.mp4" type="video/mp4">
+  <source src="rabbit320.webm" type="video/webm">
+  <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+</video>
+
+ +

Esto nos dará un resultado que se parece a esto:

+ +

A video player showing a poster image before it plays. The poster image says HTML5 video example, OMG hell yeah!Las nuevas características son:

+ +
+
{{htmlattrxref("width","video")}} y {{htmlattrxref("height","video")}}
+
Puede controlar el tamanño con estos atributos o con  {{Glossary("CSS")}}. En ambos casos, los vídeos mantienen su relación anchura - altura nativa. Si la relación de aspecto no se mantiene con los tamañis establecidos, el vídeo crecerá para rellenar el espacio horizontalmente y el el espacio sin rellenar sólo recibirá un color de fondo sólido de forma predeterminada.
+
{{htmlattrxref("autoplay","video")}}
+
Hace que el audio o el vídeo empiece a reproducirse de inmediato, mientras se carga el resto de la página. Le aconsejamos que no utilice vídeo (o audio) de reproducción automática en sus sitios, ya que los usuarios pueden encontralo molesto.
+
{{htmlattrxref("loop","video")}}
+
Hace que el vídeo (o audio) comience a reproducirse cada vez que finaliza.Esto puede en ocasiones resultar molesto, así que utilizalo solo si es realmente necesario.
+
{{htmlattrxref("muted","video")}}
+
Hace que los medios se reproduzcan con el sonido apagado de forma predeterminada.
+
{{htmlattrxref("poster","video")}}
+
La URL de una imagen que se mostrará antes de reproducir el vídeo. Está destinado a ser utilizado para una pantalla de presentación o pantalla publicitaria (miniatura del vídeo).
+
{{htmlattrxref("preload","video")}}
+
+

Se utiliza para almacenar en búfer archivos grandes; Puede tomar uno de estos tres valores:

+ +
    +
  • "none" no almacena el archivo en el búfer
  • +
  • "auto" almacena el archivo multimedia
  • +
  • "metadata" almacena solo los metadatos del archivo
  • +
+
+
+ +

Puedes encontrar el ejemplo anterior disponible en  play live on Github (también see the source code.)  Tenga en cuenta que hemos incluido el atributo autoplay en la versión en vivo  — Si el vídeo comienza a reproducirse tan pronto como se cargue la página no podrá ver la miniatura!

+ +

El elemento <audio>

+ +

El elemento  {{htmlelement("audio")}} funciona exactamente de la misma forma que el elemento {{htmlelement("video")}}, con algunas pequeñas diferencias como se describe a continuación. Un ejemplo típico podría ser así:

+ +
<audio controls>
+  <source src="viper.mp3" type="audio/mp3">
+  <source src="viper.ogg" type="audio/ogg">
+  <p>Your browser doesn't support HTML5 audio. Here is a <a href="viper.mp3">link to the audio</a> instead.</p>
+</audio>
+ +

Esto produce algo como lo siguiente en un navegador:

+ +

A simple audio player with a play button, timer, volume control, and progress bar

+ +
+

Nota: Puedes reproducir este ejemplo de audio en Github (también, puedes ver el código fuente del reproductor de audio.)

+
+ +

Esto ocupa menos espacio que un reproductor de video, ya que no hay un componente visual; solo necesita mostrar los controles para reproducir el audio. Otras diferencias con respecto al video HTML5 son las siguentes:

+ + + +

Además de esto, <audio> admite las mismas características que  <video> — revisa las secciones anteriores para obtener más información sobre ellas.

+ +

Reinicio de la reproducción multimedia

+ +

En cualquier momento, puede restablecer los medios al principio—incluyendo el proceso de selección de la mejor fuente de medios, si se especifica más de una usando {{HTMLElement("source")}} elementos—llamando al elemento {{domxref("HTMLMediaElement.load", "load()")}} method:

+ +
var mediaElem = document.getElementById("my-media-element");
+mediaElem.load();
+ +

Detecting track addition and removal

+ +

You can monitor the track lists within a media element to detect when tracks are added to or removed from the element's media. For example, you can watch for the {{event("addtrack")}} event being fired on the associated {{domxref("AudioTrackList")}} object (retrieved via {{domxref("HTMLMediaElement.audioTracks")}}) to be informed when audio tracks are added to the media:

+ +
var mediaElem = document.querySelector("video");
+mediaElem.audioTracks.onaddtrack = function(event) {
+  audioTrackAdded(event.track);
+}
+
+ +

Encontraras mas documentacion acerca de esto en nuestra {{domxref("TrackEvent")}} documentacion.

+ +

Displaying video text tracks

+ +

Now we'll discuss a slightly more advanced concept that is really useful to know about. Many people can't or don't want to hear the audio/video content they find on the Web, at least at certain times. For example:

+ + + +

Wouldn't it be nice to be able to provide these people with a transcript of the words being spoken in the audio/video? Well, thanks to HTML5 video you can, with the WebVTT format and the {{htmlelement("track")}} element.

+ +
+

Note: "Transcribe" means "to write down spoken words as text." The resulting text is a "transcript."

+
+ +

WebVTT is a format for writing text files containing multiple strings of text along with metadata such as what time in the video you want each text string to be displayed, and even limited styling/positioning information. These text strings are called cues, and you can display different types for different purposes, the most common being:

+ +
+
subtitles
+
Translations of foreign material, for people who don't understand the words spoken in the audio.
+
captions
+
Synchronized transcriptions of dialog or descriptions of significant sounds, to let people who can't hear the audio understand what is going on.
+
timed descriptions
+
Text for conversion into audio, to serve people with visual impairments.
+
+ +

A typical WebVTT file will look something like this:

+ +
WEBVTT
+
+1
+00:00:22.230 --> 00:00:24.606
+This is the first subtitle.
+
+2
+00:00:30.739 --> 00:00:34.074
+This is the second.
+
+  ...
+
+ +

To get this displayed along with the HTML media playback, you need to:

+ +
    +
  1. Save it as a .vtt file in a sensible place.
  2. +
  3. Link to the .vtt file with the {{htmlelement("track")}} element. <track> should be placed within <audio> or <video>, but after all <source> elements. Use the {{htmlattrxref("kind","track")}} attribute to specify whether the cues are subtitles, captions, or descriptions. Further, use {{htmlattrxref("srclang","track")}} to tell the browser what language you have written the subtitles in.
  4. +
+ +

Here's an example:

+ +
<video controls>
+    <source src="example.mp4" type="video/mp4">
+    <source src="example.webm" type="video/webm">
+    <track kind="subtitles" src="subtitles_en.vtt" srclang="en">
+</video>
+ +

This will result in a video that has subtitles displayed, kind of like this:

+ +

Video player with stand controls such as play, stop, volume, and captions on and off. The video playing shows a scene of a man holding a spear-like weapon, and a caption reads "Esta hoja tiene pasado oscuro."

+ +

For more details, please read Adding captions and subtitles to HTML5 video. You can find the example that goes along with this article on Github, written by Ian Devlin (see the source code too.) This example uses some JavaScript to allow users to choose between different subtitles. Note that to turn the subtitles on, you need to press the "CC" button and select an option — English, Deutsch, or Español. 

+ +
+

Note: Text tracks also help you with {{glossary("SEO")}}, since search engines especially thrive on text. Text tracks even allow search engines to link directly to a spot partway through the video.

+
+ +

Active learning: Embedding your own audio and video

+ +

For this active learning, we'd (ideally) like you to go out into the world and record some of your own video and audio — most phones these days allow you to record audio and video very easily, and provided you can transfer it on to your computer, you can use it. You may have to do some conversion to end up with a WebM and MP4 in the case of video, and an MP3 and Ogg in the case of audio, but there are enough programs out there to allow you to do this without too much trouble, such as Miro Video Converter and Audacity. We'd like you to have a go!

+ +

If you are unable to source any video or audio, then you can feel free to use our sample audio and video files to carry out this exercise. You can also use our sample code for reference.

+ +

We would like you to:

+ +
    +
  1. Save your audio and video files in a new directory on your computer.
  2. +
  3. Create a new HTML file in the same directory, called index.html.
  4. +
  5. Add <audio> and <video> elements to the page; make them display the default browser controls.
  6. +
  7. Give both of them <source> elements so that browsers will find the audio format they support best and load it. These should include type attributes.
  8. +
  9. Give the <video> element a poster that will be displayed before the video starts to be played. Have fun creating your own poster graphic.
  10. +
+ +

For an added bonus, you could try researching text tracks, and work out how to add some captions to your video.

+ +

Summary

+ +

And that's a wrap; we hope you had fun playing with video and audio in web pages! In the next article, we'll look at other ways of embedding content on the Web, using technologies like {{htmlelement("iframe")}} and {{htmlelement("object")}}.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Images_in_HTML", "Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies", "Learn/HTML/Multimedia_and_embedding")}}

+ +

In this module

+ + + +
+
+ + diff --git "a/files/es/learn/html/tablas/conceptos_b\303\241sicos_de_las_tablas_html/index.html" "b/files/es/learn/html/tablas/conceptos_b\303\241sicos_de_las_tablas_html/index.html" new file mode 100644 index 0000000000..7259adf427 --- /dev/null +++ "b/files/es/learn/html/tablas/conceptos_b\303\241sicos_de_las_tablas_html/index.html" @@ -0,0 +1,563 @@ +--- +title: Conceptos básicos de las tablas HTML +slug: Learn/HTML/Tablas/Conceptos_básicos_de_las_tablas_HTML +translation_of: Learn/HTML/Tables/Basics +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/HTML/Tables/Advanced", "Learn/HTML/Tables")}}
+ +

Este artículo te ayudará a comenzar con las tablas HTML. Vamos a exponer conceptos básicos como filas y celdas, encabezados, celdas que abarcan múltiples columnas y filas, y la forma de agrupar todas las celdas de una columna para aplicarles estilo.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (ver Introducción al HTML).
Objetivo:Adquirir conocimientos básicos de las tablas HTML.
+ +

¿Qué es una tabla?

+ +

Una tabla es un conjunto estructurado de datos distribuidos en filas y columnas (datos tabulados). Una tabla permite buscar con rapidez y facilidad valores entre diferentes tipos de datos que indiquen algún tipo de conexión. Por ejemplo, una persona y su edad, o un día de la semana o el horario de una piscina municipal.

+ +

Una tabla de datos de ejemplo que muestra los nombres y las edades de algunas personas: Chris 38, Dennis 45, Sarah 29, Karen 47.

+ +

Una tabla de datos que muestra unos horarios de clases natación

+ +

Las tablas se utilizan con mucha frecuencia en la sociedad desde hace años, como lo demuestra este documento censal de los EUA de 1800:

+ +

Un pergamino muy antiguo; cuesta un poco leer los datos, pero muestra con claridad que las tablas de datos ya se utilizaban en 1800.

+ +

Por lo tanto, no es de extrañar que los creadores de HTML proporcionen un medio con el que estructurar y presentar datos en tablas en la web.

+ +

¿Cómo funciona una tabla?

+ +

El aspecto básico de una tabla es que es un elemento rígido. Es fácil interpretar la información haciendo asociaciones visuales entre los encabezados de las filas y las columnas. Por ejemplo, observa la tabla siguiente y busca un gigante de gas joviano con 62 lunas. Puedes encontrar la respuesta asociando los encabezados de la fila y la columna correspondientes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Datos sobre los planetas de nuestro sistema solar (datos planetarios tomados de la hoja técnica sobre datos planetarios de la NASA (Nasa's Planetary Fact Sheet - Metric).
NombreMasa (1024 kg)Diámetro (km)Densidad (kg/m3)Gravedad (m/s2)Duración del día (horas)Distancia del Sol (106km)Temperatura media (°C)Número de lunasObservaciones
Planetas terrestresMercurio0,3304.8795.4273,74.222,657,91670El más cercano al Sol
Venus4,8712.1045.2438,92.802,0108,24640
La Tierra5,9712.7565.5149,824,0149,6151Nuestro planeta
Marte0,6426.7923.9333,724,7227,9-652El planeta rojo
Planetas jovianosLos gigantes de gasJúpiter1.898142.9841.32623,19,9778,6-11067El planeta más grande
Saturno568120.5366879,010,71.433,5-14062
Los gigantes de hieloUrano86,851.1181.2718,717,22.872,5-19527
Neptuno10249.5281.63811,016,14.495,1-20014
Planetas enanosPlutón0,01462.3702.0950,7153,35.906,4-2255Desclasificado como planeta en 2006, pero aún es una cuestión polémica.
+ +

Cuando se hace correctamente, incluso las personas ciegas pueden interpretar los datos de una tabla HTML. Una tabla HTML bien hecha debe mejorar la experiencia de los usuarios videntes e invidentes por igual.

+ +

Dar estilo a las tablas

+ +

También puedes echar un vistazo al ejemplo vivo en GitHub. Observarás que la tabla que encontrarás allí tiene un aspecto más legible; esto se debe a que la tabla que ves en esta página tiene un estilo mínimo, mientras que en la de la versión de GitHub se ha aplicado un CSS más significativo.

+ +

No te hagas ilusiones; para que las tablas sean efectivas en la web, debes proporcionar cierta información de estilo con CSS, así como una buena estructura sólida con HTML. En este módulo nos centramos en la parte HTML; para averiguar sobre la parte del CSS debes visitar nuestro artículo Aplicar estilo a las tablas.

+ +

En este módulo no nos vamos a centrar en el CSS, sino que te vamos a proporcionar una hoja de estilo de CSS que dará a tus tablas algo más de legibilidad de la que se obtiene por defecto si no se proporciona ningún estilo. Puedes encontrar la hoja de estilo aquí, así como también una plantilla HTML para aplicar la hoja de estilo (te darán un buen punto de partida para experimentar con las tablas HTML).

+ +

¿Cuándo no debes usar tablas HTML?

+ +

Las tablas HTML están pensadas para utilizarse con datos tabulados. Por desgracia, mucha gente utiliza las tablas HTML para hacer compaginaciones de páginas web. Por ejemplo, una fila para contener la cabecera, una fila para contener las columnas de contenido, una fila para contener el pie de página, etc. Puede encontrar más detalles y un ejemplo en Diseños de página en nuestro Módulo de aprendizaje de accesibilidad. Se solía hacer este uso de las tablas porque la compatibilidad CSS entre navegadores solía ser terrible. Los diseños de tablas son mucho menos comunes hoy en día, pero aún se pueden ver en algunos rincones de la web.

+ +

En resumen, es una mala idea usar tablas para el diseño en lugar de las técnicas de diseño CSS. Las razones principales son las siguientes:

+ +
    +
  1. Las tablas de diseño reducen la accesibilidad para los usuarios con discapacidad visual: Los lectores de pantalla que utilizan las personas con visibilidad reducida interpretan las etiquetas de una página HTML y leen su contenido para el usuario. Puesto que las tablas no son la herramienta adecuada para el diseño y el marcado es más complejo que con las técnicas de diseño CSS, la salida de los lectores de pantalla será confusa para estos usuarios.
  2. +
  3. Las tablas generan estructuras incorrectas: Como ya se mencionó, los diseños de tabla suelen involucrar estructuras de marcado más complejas que las técnicas de diseño. Esto puede dificultar la escritura, el mantenimiento y la depuración del código.
  4. +
  5. Las tablas no tienen respuesta adaptativa automática: Cuando usas contenedores de diseño adecuados (tales como {{HTMLElement ("header")}}, {{HTMLElement ("section")}}, {{HTMLElement ("article")}} o {{HTMLElement ("div")}}), su ancho predeterminado es el 100% de su elemento padre. En cambio, las tablas se dimensionan de forma predeterminada según su contenido, por lo que se necesitan medidas adicionales para que el diseño de la tabla funcione de manera efectiva en todos los dispositivos.
  6. +
+ +

Aprendizaje activo: Crea tu primera tabla

+ +

Ya hemos hablado bastante sobre la teoría de las tablas, así que veamos un ejemplo práctico y construyamos una tabla simple.

+ +
    +
  1. En primer lugar, haz una copia local de blank-template.html y minimal-table.css en un directorio nuevo de tu ordenador.
  2. +
  3. El contenido de cada tabla está delimitado entre estas dos etiquetas: <table></table>. Añádelas al cuerpo de tu código HTML.
  4. +
  5. El contenedor más pequeño dentro de una tabla es una celda, que se crea con un elemento <td> ('td' significa 'table data', datos de tabla). Añade lo siguiente dentro de tus etiquetas de tabla: +
    <td>Hola, soy tu primera celda.</td>
    +
  6. +
  7. Si quieres una fila de cuatro celdas, tienes que copiar estas etiquetas tres veces. Actualiza el contenido de la tabla para que se vea así: +
    <td>Hola, soy tu primera celda.</td>
    +<td>Soy tu segunda celda.</td>
    +<td>Soy tu tercera celda.</td>
    +<td>Soy tu cuarta celda.</td>
    +
  8. +
+ +

Como verás, las celdas no se colocan una debajo de la otra, sino que se alinean automáticamente entre sí en la misma fila. Cada elemento <td> crea una sola celda, y juntas forman la primera fila. Cada celda que agregamos hace crecer la fila.

+ +

Para detener el crecimiento de esta fila y comenzar a colocar las celdas posteriores en una segunda fila, necesitamos usar el elemento <tr> ('tr' significa 'table raw', fila de tabla). Vamos a verlo en detalle.

+ +
    +
  1. Coloca las cuatro celdas que has creado dentro de las etiquetas <tr>, de esta forma: + +
    <tr>
    +  <td>Hola, soy tu primera celda.</td>
    +  <td>Soy tu segunda celda.</td>
    +  <td>Soy tu tercera celda.</td>
    +  <td>Soy tu cuarta celda.</td>
    +</tr>
    +
  2. +
  3. Ahora que has hecho una fila, intenta hacer una o dos más: cada fila debe estar delimitada por un elemento <tr> adicional, con cada celda contenida en un <td>.
  4. +
+ +

Esto debería dar como resultado una tabla similar a la siguiente:

+ + + + + + + + + + + + + + + + +
Hola, soy tu primera celda.Soy tu segunda celda.Soy tu tercera celda.Soy tu cuarta celda.
Segunda fila, primera celda.Celda 2.Celda 3.Celda 4.
+ +
+

Nota: También puedes encontrar esto en GitHub como simple-table.html (consúltalo en vivo).

+
+ +

Añadir encabezados con elementos <th>

+ +

Ahora nos vamos a centrar en los encabezados de tabla: celdas especiales que van al comienzo de una fila o columna y definen el tipo de datos que contiene esa fila o columna (por ejemplo, observa las celdas «Propietario» y «Edad» en el primer ejemplo que se muestra en este artículo). Para ilustrar por qué son útiles, echa un vistazo al ejemplo de tabla siguiente. En primer lugar, el código fuente:

+ +
<table>
+  <tr>
+    <td>&nbsp;</td>
+    <td>Knocky</td>
+    <td>Flor</td>
+    <td>Ella</td>
+    <td>Juan</td>
+  </tr>
+  <tr>
+    <td>Raza</td>
+    <td>Jack Russell</td>
+    <td>Caniche</td>
+    <td>Perro callejero</td>
+    <td>Cocker Spaniel</td>
+  </tr>
+  <tr>
+    <td>Edad</td>
+    <td>16</td>
+    <td>9</td>
+    <td>10</td>
+    <td>5</td>
+  </tr>
+  <tr>
+    <td>Propietario</td>
+    <td>Suegra</td>
+    <td>Yo</td>
+    <td>Yo</td>
+    <td>Cuñada</td>
+  </tr>
+  <tr>
+    <td>Hábitos alimentarios</td>
+    <td>Come las sobras de todos</td>
+
+<td>Mordisquea la comida</td>
+    <td>Come en abundancia</td>
+
+<td>Come hasta que revienta</td>
+  </tr>
+</table>
+ +

Ahora observa la tabla representada:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KnockyFlorEllaJuan
RazaJack RussellCanichePerro callejeroCocker Spaniel
Edad169105
PropietarioSuegraYoYoCuñada
Hábitos alimentariosCome las sobras de todosMordisquea la comidaCome en abundanciaCome hasta que revienta
+ +

El problema aquí es que, si bien puedes distinguir lo que sucede, no es tan fácil cruzar datos de referencia. Sería mucho mejor si los encabezados de las columnas y las filas se destacasen de alguna manera.

+ +

Aprendizaje activo: encabezados de tabla

+ +

Intentemos mejorar esta tabla.

+ +
    +
  1. Primero, haz una copia local de nuestros archivos dogs-table.html y minimal-table.css en un directorio nuevo de tu ordenador. El HTML contiene el mismo ejemplo sobre perros que viste arriba.
  2. +
  3. Para reconocer los encabezados de la tabla como encabezados, tanto visual como semánticamente, puedes usar el elemento <th> ('th' significa 'table header', encabezado de tabla). Funciona exactamente igual que un <td>, excepto que denota un encabezado, no una celda normal. Entra en el código HTML, y cambiar todos los elementos <td> que delimitan los encabezados de tabla por elementos <th>.
  4. +
  5. Guarda tu HTML y cárgalo en un navegador. Los encabezados deberían verse como tal.
  6. +
+ +
+

Nota: Puedes encontrar nuestro ejemplo terminado en dogs-table-fixed.html en GitHub (o consultarlo en vivo).

+
+ +

¿Por qué son útiles los encabezados?

+ +

Ya hemos respondido parcialmente a esta pregunta: es más fácil encontrar los datos que buscas cuando los encabezados se destacan con claridad, y el diseño suele presentar un aspecto mejor.

+ +
+

Nota: Los encabezados de las tablas vienen con un estilo predeterminado: están en negrita y centrados (incluso si no añades tu estilo propio a la tabla) para que destaquen.

+
+ +

Los encabezados de tabla también presentan otra ventaja: junto con el atributo de scope (que veremos en el próximo artículo), mejoran la accesibilidad de las tablas porque asocian cada encabezado con todos los datos de la misma fila o columna. Así que los lectores de pantalla pueden leer una fila o columna de datos a la vez, lo cual es bastante útil.

+ +

Celdas que abarcan varias filas y columnas

+ +

A veces queremos que las celdas abarquen varias filas o columnas. Toma el ejemplo siguiente, que muestra los nombres de algunos animales comunes. En algunos casos, queremos mostrar los nombres de los machos y las hembras junto al nombre del animal. A veces no lo queremos, y en tales casos queremos que el nombre del animal abarque toda la tabla.

+ +

El marcado inicial se ve así:

+ +
<table>
+  <tr>
+    <th>Animales</th>
+  </tr>
+  <tr>
+    <th>Hipopótamo</th>
+  </tr>
+  <tr>
+    <th>Caballo</th>
+    <td>Yegua</td>
+  </tr>
+  <tr>
+    <td>Semental</td>
+  </tr>
+  <tr>
+
+<th>Cocodrilo</th>
+  </tr>
+  <tr>
+
+<th>Pollo</th>
+
+<td>Gallina</td>
+  </tr>
+  <tr>
+    <td>Gallo</td>
+  </tr>
+</table>
+ +

Pero la salida no nos da exactamente lo que queremos:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Animales
Hipopótamo
CaballoYegua
Semental
Cocodrilo
PolloGallina
Gallo
+ +

Necesitamos una forma de hacer que «Animales», «Hipopótamo» y «Cocodrilo» se extiendan dos columnas más allá, y «Caballo» y «Pollo» se extiendan dos filas más abajo. Por fortuna, los encabezados de tabla y las celdas tienen los atributos colspan y rowspan, que nos permiten hacer exactamente esas cosas. Ambos aceptan un valor numérico sin unidades, que es igual al número de filas o columnas que desea abarcar. Por ejemplo, colspan="2" extiende una celda dos columnas más allá.

+ +

Usemos colspan y rowspan para mejorar esta tabla.

+ +
    +
  1. Primero, haz una copia local de nuestros archivos animals-table.html y minimal-table.css en un directorio nuevo de tu ordenador. El HTML contiene el mismo ejemplo sobre perros que viste arriba.
  2. +
  3. Luego, usa colspan para extender las celdas «Animales», «Hipopótamo» y «Cocodrilo» dos columnas más allá.
  4. +
  5. Por último, usa rowspan para extender las celdas de «Caballo» y «Pollo» dos filas más abajo.
  6. +
  7. Guarda tu código y ábrelo en un navegador para ver la mejora.
  8. +
+ +
+

Nota: Puedes encontrar nuestro ejemplo terminado en animals-table-fixed.html en GitHub (o consultarlo en vivo).

+
+ + +
+ +

Proporcionar un estilo común a las columnas.

+ +

Hay una última característica de la que queremos hablar en este artículo antes de continuar. El HTML tiene un método para definir información de estilo para una columna completa de datos en un solo lugar: los elementos <col> y <colgroup>. Estos atributos existen porque especificar el estilo de las columnas puede resultar enojoso e ineficiente; en general hay que especificar la información de estilo en cada <td> o <th> de la columna, o utilizar un selector complejo como {{cssxref(":nth-child()")}}.

+ +

Tomemos el ejemplo sencillo siguiente:

+ +
<table>
+  <tr>
+
+<th>Dato 1</th>
+    <th style="background-color: yellow">Dato 2</th>
+  </tr>
+  <tr>
+    <td>Calcuta</td>
+    <td style="background-color: yellow">Pizza</td>
+  </tr>
+  <tr>
+    <td>Robots</td>
+    <td style="background-color: yellow">Jazz</td>
+  </tr>
+</table>
+ +

Esto nos da el resultado siguiente:

+ + + + + + + + + + + + + + + + +
Dato 1Dato 2
CalcutaNaranja
RobotsJazz
+ +

Esto no es ideal, porque hay que repetir la información de estilo en las tres celdas de la columna (en un proyecto real probablemente habría definida una clase class en las tres celdas y el estilo se especificaría en una hoja de estilo por separado). En vez de hacer esto, podemos especificar la información una sola vez, con un elemento <col>. Los elementos <col> se especifican dentro de un contenedor <colgroup> justo debajo de la etiqueta de apertura <table>. Podríamos crear el mismo efecto que vemos arriba especificando nuestra tabla de la manera siguiente:

+ +
<table>
+  <colgroup>
+    <col>
+    <col style="background-color: yellow">
+  </colgroup>
+  <tr>
+
+<th>Dato 1</th>
+
+<th>Dato 2</th>
+  </tr>
+  <tr>
+    <td>Calcuta</td>
+    <td>Pizza</td>
+  </tr>
+  <tr>
+    <td>Robots</td>
+    <td>Jazz</td>
+  </tr>
+</table>
+ +

En efecto, definimos dos tipos de «columnas de estilo», una que especifica la información para la aplicación de estilo en cada columna. No aplicamos estilo a la primera columna, sino que aún tenemos que incluir un elemento <col> en blanco; de lo contrario, el estilo también se aplicaría a la primera columna.

+ +

Si quisiéramos aplicar la información de estilo a ambas columnas, podríamos incluir un elemento <col> con un atributo span, como este:

+ +
<colgroup>
+  <col style="background-color: yellow" span="2">
+</colgroup>
+ +

Al igual que colspan y rowspan, span toma un valor numérico sin unidades que especifica el número de columnas a las que se desea aplicar el estilo.

+ +

Aprendizaje activo: colgroup y col

+ +

Ahora es el momento de intentarlo tú mismo.

+ +

A continuación puedes ver el horario de una profesora de idiomas. El viernes tiene que enseñar holandés todo el día, pero también enseña alemán durante unas horas los martes y los jueves, y quiere resaltar las columnas que contienen los días que da clase.

+ +

{{EmbedGHLiveSample("learning-area/html/tables/basic/timetable-fixed.html", '100%', 320)}}

+ +

Recrea la tabla a partir de los pasos siguientes.

+ +
    +
  1. Primero, haz una copia local de nuestro archivo timetable.html en un directorio nuevo de tu ordenador. El HTML contiene la misma tabla que viste arriba, menos la información de estilo de las columnas.
  2. +
  3. Añade un elemento <colgroup> en la parte superior de la tabla, justo debajo de la etiqueta <table>, en la que puedes añadir tus elementos <col> (consulta los pasos restantes a continuación).
  4. +
  5. Las dos primeras columnas deben dejarse sin estilo.
  6. +
  7. Añade un color de fondo a la tercera columna. El valor para tu atributo de style es background-color:#97DB9A;
  8. +
  9. Establece un ancho distinto para la cuarta columna. El valor de tu atributo de style es width: 42px;
  10. +
  11. Añade un color de fondo a la quinta columna. El valor para tu atributo de style es background-color:#97DB9A;
  12. +
  13. Añade un color de fondo diferente más un borde a la sexta columna, para indicar que este es un día especial porque da clases de un idioma diferente. Los valores para tu atributo de style son background-color:#DCC48E; border:4px solid #C1437A;
  14. +
  15. Los últimos dos días los tiene libres, así que no establezcas ningún color de fondo, pero sí un valor para el ancho; el valor para el atributo de style es width: 42px;
  16. +
+ +

Mira cómo sigue en el ejemplo. Si te encallas o quieres verificar tu trabajo, puedes encontrar nuestra versión en GitHub como timetable-fixed.html (o también puedes consultarlo en vivo).

+ +

Resumen

+ +

Con esto casi hemos abarcado todos los conceptos básicos de las tablas HTML. En el próximo artículo, veremos algunas características un poco más avanzadas de las tablas y comenzaremos a pensar acerca de su accesibilidad para las personas con discapacidad visual.

+ +
{{NextMenu("Learn/HTML/Tables/Advanced", "Learn/HTML/Tables")}}
+ +
+

En este módulo

+ + +
diff --git a/files/es/learn/html/tablas/funciones_avanzadas_de_las_tablas_html_y_accesibilidad/index.html b/files/es/learn/html/tablas/funciones_avanzadas_de_las_tablas_html_y_accesibilidad/index.html new file mode 100644 index 0000000000..a74817c5d4 --- /dev/null +++ b/files/es/learn/html/tablas/funciones_avanzadas_de_las_tablas_html_y_accesibilidad/index.html @@ -0,0 +1,471 @@ +--- +title: Funciones avanzadas de las tablas HTML y accesibilidad +slug: Learn/HTML/Tablas/Funciones_avanzadas_de_las_tablas_HTML_y_accesibilidad +translation_of: Learn/HTML/Tables/Advanced +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Tables/Basics", "Learn/HTML/Tables/Structuring_planet_data", "Learn/HTML/Tables")}}
+ +

En el segundo artículo de este módulo, analizamos algunas características más avanzadas de las tablas HTML, como los subtítulos/resúmenes, la agrupación de filas en las secciones del encabezado, el cuerpo y el pie de página; y también analizamos la accesibilidad de las tablas para usuarios con discapacidad visual.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de HTML (ver Introducción al HTML).
Objetivo:Aprender las características más avanzadas de las tablas HTML y la accesibilidad de las tablas.
+ +

Añadir un subtítulo a tu tabla con <caption>

+ +

Puedes dar un título a tu tabla colocándolo dentro de un elemento {{htmlelement ("caption")}} y anidándolo dentro del elemento {{htmlelement ("table")}}. Debes ponerlo justo debajo de la etiqueta de apertura <table>.

+ +
<table>
+  <caption>Dinosaurios en el período Jurásico</caption>
+
+  ...
+</table>
+ +

Como puedes deducir a partir del breve ejemplo anterior, el título debe contener una descripción del contenido de la tabla. Esto es útil para todos los lectores que deseen descubrir de un vistazo si la tabla les resulta útil mientras ojean la página, pero es útil especialmente para usuarios ciegos. En lugar de que un lector de pantalla lea el contenido de muchas celdas solo para averiguar de qué trata la tabla, el lector puede contar con el título para luego decidir si leer la tabla con mayor detalle.

+ +

Los subtítulos se colocan directamente debajo de la etiqueta <table>.

+ +
+

Nota: El atributo {{htmlattrxref("summary","table")}} también se puede usar en el elemento table para proporcionar una descripción; los lectores de pantalla también lo leen. Sin embargo, recomendamos usar el elemento caption, porque {{htmlattrxref("summary","table")}} está {{glossary("obsoleto")}} conforme a la especificación HTML5 y porque los usuarios sin discapacidad visual no pueden leerlo (no aparece en la página).

+
+ +

Aprendizaje activo: Añadir un subtítulo

+ +

Vamos a probarlo con un ejemplo del artículo anterior.

+ +
    +
  1. Abre el ejemplo del horario de clases de la profesora de idiomas del final de conocimientos básicos de las tablas HTML, o haz una copia local de nuestro archivo timetable-fixed.html.
  2. +
  3. Añade un título adecuado a la tabla.
  4. +
  5. Guarda tu código, ábrelo en un navegador y observa qué aspecto presenta.
  6. +
+ +
+

Nota: Puedes encontrar nuestra versión en GitHub: consulta timetable-caption.html (mirar en vivo).

+
+ +

Añadir estructura con <thead>, <tfoot> y <tbody>

+ +

A medida que la estructura de las tablas se vuelve más compleja, es útil darles una estructura más definida. Una forma clara de hacerlo es con {{htmlelement ("thead")}}, {{htmlelement ("tfoot")}} y {{htmlelement ("tbody")}}, que te permiten marcar un encabezado, un pie de página y una sección del cuerpo de la tabla.

+ +

Estos elementos no mejoran las características de accesibilidad de la tabla para los usuarios de lectores de pantalla ni su aspecto visual en sí. Sin embargo, son muy útiles para la aplicación de estilo y la compaginación, porque actúan como soportes útiles para añadir CSS a tu tabla. Como ejemplos interesantes, en el caso de una tabla extensa, puedes hacer que el encabezado y el pie de página se repitan en cada página impresa, y también que el cuerpo de la tabla se muestre en una sola página y desplazarte por los contenidos arriba y abajo con la barra de desplazamiento.

+ +

Para utilizarlos:

+ + + +
+

Nota: <tbody> se incluye siempre en todas las tablas de forma implícita si no lo especificas en tu código. Para comprobarlo, abre uno de tus ejemplos anteriores que no incluya <tbody> y mira el código HTML en las herramientas de desarrollo de tu navegador; verás que el navegador ha añadido esta etiqueta. Quizás te preguntes por qué deberías molestarte en incluirlo. Debes hacerlo para tener más control sobre la estructura y el estilo de la tabla.

+
+ +

Aprendizaje activo: Añadir estructura a la tabla

+ +

Pongamos en acción estos elementos nuevos.

+ +
    +
  1. En primer lugar, haz una copia local de spending-record.html y minimal-table.css en una carpeta nueva de tu ordenador.
  2. +
  3. Intenta abrirlo en un navegador: observarás que se ve bien, pero podría mejorarse. La fila «SUM», que contiene una suma de las cantidades gastadas, parece estar en el lugar equivocado, y faltan algunos detalles del código.
  4. +
  5. Coloca la fila de encabezados dentro de un elemento <thead>, la fila «SUM» dentro de un elemento <tfoot>, y el resto del contenido dentro de un elemento <tbody>.
  6. +
  7. Guarda y actualiza, y observa que añadir el elemento <tfoot> ha provocado que la fila «SUM» pase al final de la tabla.
  8. +
  9. Luego, añade un atributo {{htmlattrxref ("colspan", "td")}} para que la celda «SUM» abarque las primeras cuatro columnas, de modo que el número aparezca en la parte inferior de la columna «Costes».
  10. +
  11. Vamos a añadir un estilo adicional sencillo a la tabla para que veas cuán útiles son estos elementos para aplicar CSS. Dentro del encabezado del documento HTML hay un elemento {{htmlelement ("style")}} vacío. Añade a este elemento las líneas de código CSS siguientes: +
    tbody {
    +  font-size: 95%;
    +  font-style: italic;
    +}
    +
    +tfoot {
    +  font-weight: bold;
    +}
    +
    +
  12. +
  13. Guarda, actualiza, y échale un vistazo al resultado. Si los elementos <tbody> y <tfoot> no estuvieran en su lugar, tendrías que escribir selectores/reglas mucho más complicados para obtener la misma aplicación de estilo.
  14. +
+ +
+

Nota: No esperamos que comprendas completamente el CSS en este momento. Aprenderás más sobre el tema cuando llegues a nuestros módulos CSS (Introducción al CSS es un buen lugar para comenzar; también tenemos un artículo específico sobre Aplicar estilo a las tablas).

+
+ +

Tu tabla final debería tener un aspecto similar al siguiente:

+ + + +

{{ EmbedLiveSample('Hidden_example', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Nota: También puedes encontrarlo en GitHub como spending-record-finished.html (o consultarlo también en vivo).

+
+ +

Anidar tablas

+ +

Es posible anidar una tabla dentro de otra, siempre que incluyas la estructura completa, incluido el elemento <table>. Por lo general, esto no se recomienda, porque se obtiene un marcado más confuso y menos accesible para los usuarios que usan lectores de pantalla, y además, en muchos casos sería posible sencillamente insertar celdas/filas/columnas adicionales en la tabla. Sin embargo, a veces es necesario, por ejemplo, si deseas importar contenido de forma sencilla desde otras fuentes.

+ +

El marcado siguiente muestra una tabla anidada simple:

+ +
<table id="tabla1">
+  <tr>
+    <th>título1</th>
+    <th>título2</th>
+    <th>título3</th>
+  </tr>
+  <tr>
+    <td id="nested">
+      <table id="tabla2">
+        <tr>
+          <td>celda1</td>
+          <td>celda2</td>
+          <td>celda3</td>
+        </tr>
+      </table>
+    </td>
+    <td>celda2</td>
+    <td>celda3</td>
+  </tr>
+  <tr>
+    <td>celda4</td>
+    <td>celda5</td>
+    <td>celda6</td>
+  </tr>
+</table>
+ +

La salida se verá así:

+ + + + + + + + + + + + + + + + + + + +
título1título2título3
+ + + + + + + + +
celda1celda2celda3
+
celda2celda3
celda4celda5celda6
+ +

Tablas para usuarios con discapacidad visual

+ +

Repasemos brevemente cómo usamos las tablas de datos. Una tabla puede ser una herramienta útil porque nos proporciona un acceso rápido a unos datos y nos permite buscar entre valores diferentes. Por ejemplo, echa un vistazo a la tabla siguiente para saber cuántos anillos se vendieron en Gante en agosto pasado. Para comprender la información que contiene la tabla, establecemos asociaciones visuales entre los datos de la tabla y sus encabezados de columna y/o fila.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Artículos vendidos en agosto de 2016
RopaAccesorios
PantalonesFaldasVestidosPulserasAnillos
BélgicaAmberes5622437223
Gante4618506115
Bruselas5127386928
Los países bajosÁmsterdam8934698538
Utrecht8012433619
+ +

Pero, ¿y si no puedes hacer esas asociaciones visuales? ¿Cómo podrías leer una tabla como la anterior? Las personas con discapacidad visual a menudo usan un lector de pantalla que les lee la información de las páginas web. Esto no resulta un problema cuando lees un texto sin formato, pero interpretar una tabla puede ser un gran desafío para una persona ciega. Sin embargo, con el marcado adecuado podemos reemplazar las asociaciones visuales por otras asociaciones de tipo programático.

+ +
+

Nota: Hay en torno a 253 millones de personas con discapacidad visual según los datos de la OMS de 2017.

+
+ +

Esta sección del artículo proporciona técnicas adicionales para conferir a las tablas la mayor accesibilidad posible.

+ +

Usar encabezados de columna y fila

+ +

Los lectores de pantalla identificarán todos los encabezados y los usarán para hacer asociaciones programáticas entre esos encabezados y las celdas con las que se relacionan. La combinación de encabezados por columna y fila identificará e interpretará los datos de cada celda para que los usuarios que usan lectores de pantalla puedan interpretar la tabla de manera similar a como lo hace un usuario sin discapacidad visual.

+ +

Ya expusimos los encabezados en nuestro artículo anterior; consulta Añadir encabezados con elementos <th>.

+ +

El atributo scope

+ +

Un nuevo tema para este artículo es el atributo {{htmlattrxref ("scope", "th")}}, que se puede añadir al elemento <th> para indicar a los lectores de pantalla exactamente para qué celdas es el encabezado. Volviendo a nuestro ejemplo anterior de registro de gastos, podrías definir los encabezados de columna inequívocamente como encabezados de columna de este modo:

+ +
<thead>
+  <tr>
+    <th scope="col">Compra</th>
+    <th scope="col">Ubicación</th>
+    <th scope="col">Fecha</th>
+    <th scope="col">Revisión</th>
+    <th scope="col">Coste (€)</th>
+  </tr>
+</thead>
+ +

Y también cada fila podría tener un encabezado definido de esta manera (si añadimos encabezados de fila y encabezados de columna):

+ +
<tr>
+  <th scope="row">Corte de pelo</th>
+
+<td>Peluquería</td>
+  <td>12/09</td>
+
+<td>Gran idea</td>
+  <td>30</td>
+</tr>
+ +

Los lectores de pantalla reconocerán el marcado estructurado de esta manera y permitirán a tus usuarios, por ejemplo, leer toda la columna o fila a la vez.

+ +

El atributo scope tiene dos valores posibles más: colgroup y rowgroup. Se utilizan para encabezados que se encuentran sobre la parte superior de varias columnas o filas. Si vuelves a echar un vistazo a la tabla «Artículos vendidos en agosto de 2016» al comienzo de esta sección, verás que la celda «Ropa» se encuentra encima de las celdas «Pantalones», «Faldas» y «Vestidos» Todas estas celdas deben estar marcadas como encabezados (<th>), pero «Ropa» es un encabezado que está por encima y define los otros tres subencabezados. Por lo tanto, «Ropa» debería incluir un atributo scope="colgroup", mientras que los demás tendrían un atributo scope="col".

+ +

Los atributos de id y encabezados

+ +

Una alternativa al uso del atributo scope es usar los atributos {{htmlattrxref ("id")}} y {{htmlattrxref ("headers", "td")}} para crear asociaciones entre encabezados y celdas. La forma en que se usan es la siguiente:

+ +
    +
  1. Añades un id único a cada elemento <th>.
  2. +
  3. Añades un atributo headers a cada elemento <td>. Cada atributo headers debe contener una lista de los id de todos los elementos <th> que actúan como encabezado de esa celda, separados por espacios.
  4. +
+ +

Esto le da a tu tabla HTML una definición explícita de la posición de cada celda en la tabla definida por los encabezados de cada columna y fila de la que forma parte, como en una hoja de cálculo. Para que funcione bien, la tabla necesita tanto encabezados de columna como encabezados de fila.

+ +

Volviendo a nuestro ejemplo de gastos, los dos fragmentos anteriores podrían reescribirse así:

+ +
<thead>
+  <tr>
+    <th id="purchase">Compra</th>
+    <th id="location">Ubicación</th>
+    <th id="date">Fecha</th>
+    <th id="evaluation">Revisión</th>
+    <th id="cost">Coste (€)</th>
+  </tr>
+</thead>
+<tbody>
+<tr>
+  <th id="haircut">Corte de pelo</th>
+  <td headers="location haircut">Peluquería</td>
+  <td headers="date haircut">12/09</td>
+  <td headers="evaluation haircut">Gran idea</td>
+  <td headers="cost haircut">30</td>
+</tr>
+
+  ...
+
+</tbody>
+ +
+

Nota: Este método crea asociaciones muy precisas entre los encabezados y las celdas de datos, pero utiliza un montón más de código de marcado y no permite errores. El enfoque scope suele bastar para la mayoría de las tablas.

+
+ +

Aprendizaje activo: jugar con scope y headers

+ +
    +
  1. Para este ejercicio final, te proponemos que primero hagas copias locales de items-sold.html y minimal-table.css en un directorio nuevo.
  2. +
  3. Ahora intenta añadir los atributos scope adecuados para hacer que esta tabla sea más accesible.
  4. +
  5. Por último, haz otra copia de los archivos originales, y esta vez añade accesibilidad a la tabla utilizando los atributos id y headers.
  6. +
+ +
+

Nota: Puedes verificar tu trabajo con nuestros ejemplos terminados: consulta items-sold-scope.html (consúltalo en vivo) y items-sold-headers.html (consúltalo en vivo).

+
+ +

Resumen

+ +

Podrías aprender algo más sobre las tablas en HTML, pero en realidad te hemos proporcionado toda la información que necesitas saber en este momento. En este punto, es posible que desees ir y aprender sobre la aplicación de estilo a tablas HTML: consulta Aplicar estilo a las tablas.

+ +
{{PreviousMenuNext("Learn/HTML/Tables/Basics", "Learn/HTML/Tables/Structuring_planet_data", "Learn/HTML/Tables")}}
+ +
+

En este módulo

+ + +
diff --git a/files/es/learn/html/tablas/index.html b/files/es/learn/html/tablas/index.html new file mode 100644 index 0000000000..7d04eb0cbf --- /dev/null +++ b/files/es/learn/html/tablas/index.html @@ -0,0 +1,34 @@ +--- +title: Tablas HTML +slug: Learn/HTML/Tablas +translation_of: Learn/HTML/Tables +--- +
{{LearnSidebar}}
+ +

Una tarea muy común en HTML es la estructuración de datos, y para esto hay múltiples elementos y atributos. Esto unido a un poco de CSS, hace que en HTML sea sencillo mostrar tablas con información sobre tu horario escolar, los horarios de una piscina local o las estadisticas de tu equipo de dinosaurios o fútbol preferido. Este módulo te guiará en todo lo que necesitas saber sobre la estructuración tabular de datos en HTML.

+ +

Requisitos previos

+ +

Antes de comenzar este módulo, deberías de saber las cosas básicas de HTML — ver Introducción a HTML.

+ +
+

Nota: Si estas trabjando en un ordenador/tableta/otro dispositivo en el que no puedes crear tus propios archivos, puedes probar la mayoría de ejemplos online en webs como JSBin o Thimble.

+
+ +

Guías

+ +

Este módulo contiene los siguientes artículos:

+ +
+
Comenzando con tablas HTML
+
Este artículo te introduce en las tablas HTML , cubriendo las cosas más basicas como las líneas y las celdas, encabezados, crear celdas de multiples líneas y columnas, y como agrupar todas las celdas en una columna con fines estilisticos.
+
Características avanzadas y accesibilidad en tablas HTML
+
En el segundo artículo de este módulo, veremos algunas características avanzadas de las tablas HTML — como subtítulos/resumenes y agrupar líneas en la cabeza, cuerpo y pie de la tabla — además de realizar tablas accesibles para aquellos usuarios con problemas de visión.
+
+ +

Evaluación

+ +
+
Estructurar datos planetarios
+
En nuestra evaluación, te proporcionamos datos sobre los planetas de nuestro sistemas solar y tu los estructurarás en una tabla HTML.
+
diff --git a/files/es/learn/html/tablas/structuring_planet_data/index.html b/files/es/learn/html/tablas/structuring_planet_data/index.html new file mode 100644 index 0000000000..e9868bb95a --- /dev/null +++ b/files/es/learn/html/tablas/structuring_planet_data/index.html @@ -0,0 +1,72 @@ +--- +title: 'Evaluación: Estructurando datos planetarios' +slug: Learn/HTML/Tablas/Structuring_planet_data +translation_of: Learn/HTML/Tables/Structuring_planet_data +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/HTML/Tables/Advanced", "Learn/HTML/Tables")}}
+ +

En nuestra evaluación te proporcionamos datos sobre los planetas de nuestro sistema solar y tu los estructurarás en una tabla HTML.

+ + + + + + + + + + + + +
Requisitos previos:Antes de comenzar esta evaluación deberías de haber leído los artículos de este módulo.
Objetivo:Comprobar si has comprendido las tablas HTML y las características asociadas.
+ +

Punto de incio

+ +

Para comenzar esta evaluación, crea una copia local de blank-template.html, minimal-table.css, y planets-data.txt en una nueva carpeta de tu ordenador.

+ +
+

Nota: Como alternativa, puedes usar una web como JSBin o Thimble para realizar tu evaluación. Puedes pegar el HTML, CSS y JavaScript en uno de estos editores online. Si el editor online que estas usando no tiene paneles separados para JavaScript/CSS, sientete libre de ponerlos en línea dentro del mismo HTML mediante el uso de <script>/<style>.

+
+ +

Resumen del proyecto

+ +

Estás trabajando en la escuela; tus estudiantes están estudiando los planetas de nuestro sistema solar y quieres proporcionarles una forma sencilla de seguir los datos para buscar hechos sobre los planetas. Una tabla HTML sería ideal — tienes que coger los datos que tienes disponibles y convertirlos en una tabla siguiendo los pasos de abajo.

+ +

La tabla finalizada debería de verse así:

+ +

+ +

También puedes ver el ejemplo aquí (no mires el código fuente — ¡no hagas trampas!)

+ + + +

Pasos para completarlo

+ +

Los siguientes pasos describen lo que necesitas para completar el ejemplo de la tabla. Todos los datos que necesitarás están en el archivo planets-data.txt. Si tienes problemas para visualizar los datos, mira el ejemplo de arriba o intentalo dibujando un diagrama.

+ +
    +
  1. Abre tu copia de blank-template.html, y comienza la tabla dándole un contenedor exterior, una cabecera y un cuerpo. No necesitas un pie de tabla en este ejemplo.
  2. +
  3. Añade el subtítulo proporcionado a tu tabla.
  4. +
  5. Añade una línea a la cabecera que contenga todos los encabezados de columna.
  6. +
  7. Crea todas las líneas con su contenido, asegurandote marcar como cabecera aquellas celdas que lo sean.
  8. +
  9. Asegurate de que el contenido esta insertado en las celdas correctas — en los datos del .txt, cada línea del planeta esta al lado de su planeta asociado.
  10. +
  11. Añade atributos para que las líneas y columnas del encabezado no se puedan confundir con las líneas, columnas o grupos de líneas a las que encabezan.
  12. +
  13. Añade un borde negro alrededor de la columna que contiene los nombres de los planetas y sus encabezados.
  14. +
+ +

Pistas y consejos

+ + + +

Evaluación

+ +

Si estas siguiendo esta evaluación como parte de un curso organizado, deberías de ser capaz de entregar tu trabajo a tu profesor(a)/mentor para ver la puntuación. Si estas aprendiendo por tu cuenta, puedes obtener la guía de puntuación preguntando en Learning Area Discourse thread o en el canal IRC #mdn en Mozilla IRC. Intenta hacer el ejercicio primero  — ¡haciendo trampas no aprenderás nada!

+ +

{{PreviousMenu("Learn/HTML/Tables/Advanced", "Learn/HTML/Tables")}}

diff --git a/files/es/learn/index.html b/files/es/learn/index.html new file mode 100644 index 0000000000..a032b43e2d --- /dev/null +++ b/files/es/learn/index.html @@ -0,0 +1,135 @@ +--- +title: Aprende sobre desarrollo web +slug: Learn +tags: + - Ayuda + - CSS + - HTML + - Inicio + - Landing + - Principiante + - TopicStub + - Web +translation_of: Learn +--- +

{{LearnSidebar}}

+ +

¡Hola! Bienvenido al área de aprendizaje de MDN. Si quieres aprender a crear tus propias páginas web, sitios o aplicaciones, has venido al lugar indicado.

+ +

El objetivo de esta área de MDN no es llevarte de «principiante» a «experto», sino de «principiante» a «cómodo». A partir de ese punto, deberías poder comenzar a abrirte camino, aprendiendo del {{web.link("/es/", "resto de MDN")}} y de otras fuentes de niveles intermedio hasta avanzado, las cuales asumen que tienes un vasto conocimiento previamente adquirido.

+ +

Si eres del todo un principiante, el desarrollo web puede ser un reto —pero no te preocupes, te llevaremos de la mano y te proveeremos de suficientes detalles para hacerte sentir cómodo y que aprendas los temas apropiadamente—. Para que te sientas como en casa, ya seas un estudiante (por tu cuenta o como parte de un grupo), un maestro buscando material para sus clases, un aficionado o alguien que simplemente desea entender mejor cómo funcionan las tecnologías web.

+ +

Novedades

+ +

El contenido del área de aprendizaje se amplía con regularidad. Se han comenzado a guardar {{web.link("/es/docs/Learn/Release_notes", "notas de publicación del área de aprendizaje")}} para mostrar lo que ha cambiado. ¡Revísalas frecuentemente para mantenerte actualizado!

+ +

Si tienes preguntas sobre temas que te gustaría que se abordaran o te parece que faltan, envía un mensaje en el Foro de discusión, de la comunidad Mozilla (sitio en inglés).

+ +
+

¿Quieres convertirte en un desarrollador de interfaz de usuario web?

+ +

Hemos elaborado un curso que incluye toda la información esencial que necesitas para alcanzar tu objetivo.

+ +

Empieza aquí

+
+ +

Dónde empezar

+ +

Para continuar, piensa cuál de las siguientes afirmaciones te describe mejor y ve a la página de inicio enlazada:

+ + + +
+

Nota: el {{web.link("/es/docs/Glossary", "glosario")}} proporciona definición de términos. Además, si tienes una pregunta específica sobre el desarrollo web, la sección de {{web.link("/es/docs/Learn/Common_questions", "preguntas frecuentes")}} te puede brindar información de gran utilidad.

+
+ +

{{LearnBox({"title":"Entrada aleatoria del glosario"})}}

+ +

Temas tratados

+ +

La siguiente es una lista de todos los temas tratados en el área de aprendizaje de MDN.

+ +
+
{{web.link("/es/docs/Learn/Getting_started_with_the_web", "Primeros pasos en la web")}}
+
Proporciona una introducción práctica al desarrollo de la web para principiantes.
+
{{web.link("/es/docs/Learn/HTML", "HTML")}}
+
HTML es el lenguaje utilizado para estructurar las diferentes partes del contenido y definir su significado o propósito. Este tema enseña el HTML en detalle.
+
{{web.link("/es/docs/Learn/CSS", "CSS")}}
+
CSS es el lenguaje que se utiliza para estilizar y organizar el contenido web, así como para añadir comportamiento tal como la animación. Este tema proporciona una amplia cobertura de CSS.
+
{{web.link("/es/docs/Learn/JavaScript", "JavaScript — Scripts dinámicos de lado del cliente")}}
+
JavaScript es el lenguaje de scripts usado para añadir funcionalidad dinámica a las páginas web. Este tema enseña todo lo esencial necesario para sentirte cómodo con la escritura y comprensión de JavaScript.
+
{{web.link("/es/docs/Learn/HTML/Forms", "Formularios HTML")}}
+
Los formularios HTML son un potente instrumento para interactuar con los usuarios — frecuentemente se utilizan para reunir datos de los usuarios, o permitirte controlar la interfaz de usuario. En los artículos enumerados a continuación, se cubrirán todos los aspectos esenciales de la estructuración, estilizado e interacción con los formularios web.
+
{{web.link("/es/docs/Learn/Accessibility", "Accesibilidad")}}
+
La accesibilidad es la práctica de hacer que el contenido web esté disponible para tantas personas como sea posible, independientemente de la discapacidad, el dispositivo, la ubicación u otros factores diferenciadores. Este tema te da todo lo que necesitas saber.
+
{{web.link("/es/docs/Learn/Performance", "Rendimiento web — hace que los sitios web sean rápidos y responsivos")}}
+
El rendimiento web es el arte de asegurarte de que las aplicaciones web se descarguen rápidamente y respondan a la interacción del usuario, independientemente del ancho de banda, el tamaño de la pantalla, la red o las capacidades del dispositivo del usuario.
+
{{web.link("/es/docs/Learn/Herramientas_y_pruebas", "Herramientas y pruebas")}}
+
Este tema abarca las herramientas que los desarrolladores utilizan para facilitar su trabajo, como las herramientas de prueba entre navegadores, analizadores de errores de código fuente, formateadores, herramientas de transformación, sistemas de control de versiones, herramientas de despliegue y marcos de desarrollo JavaScript de lado del cliente.
+
{{web.link("/es/docs/Learn/Server-side", "Programación del lado servidor")}}
+
Aunque te concentres en el desarrollo web de lado del cliente, sigue siendo útil saber cómo funcionan los servidores y las características del código del lado del servidor. Este tema proporciona una introducción general a cómo funciona el lado del servidor y tutoriales detallados que muestran cómo construir una aplicación de lado del servidor utilizando dos marcos de desarrollo populares: Django (Python) y Express (Node.js).
+
+ +

Obtener el código de los ejemplos

+ +

Todo el código de los ejemplos propuestos en el área de aprendizaje se encuentra disponible en GitHub. Si quieres, los puedes copiar para tenerlos en tu ordenador, la manera más fácil es descargar un ZIP de la última rama del código maestro.

+ +

Si prefieres copiar el código de una forma más flexible que te permita actualizaciones automáticas, puedes seguir estas instrucciones más complejas:

+ +
    +
  1. Instala Git en tu máquina. Este es el sistema de control de versiones de software con el que trabaja GitHub principalmente.
  2. +
  3. Abre tu consola de comandos (Windows) o terminal (Linux, MacOS X)
  4. +
  5. Para copiar el repositorio del área de aprendizaje a un directorio llamado learning-area en la ubicación actual, en la ventana de tu Terminal o en la línea de comandos, debes usar el siguiente comando. +
    git clone https://github.com/mdn/learning-area
    +
  6. +
  7. Ahora puedes entrar en el directorio y encontrar todos los archivos que descargaste (posiblemente con el explorador de archivos o el comando cd).
  8. +
+ +

Puedes actualizar el repositorio learning-area con los últimos cambios que se hayan hecho a la versión principal en GitHub con los siguientes pasos:

+ +
    +
  1. En tu intérprete de comandos/terminal, ve dentro del directorio learning-area usando cd. Por ejemplo, si estuvieras en el directorio padre: + +
    cd learning-area
    +
  2. +
  3. Puedes realizar actualizaciones al repositorio usando el siguiente comando: +
    git pull
    +
  4. +
+ +

Contáctanos

+ +

Si tienes alguna pregunta o deseas saber hacia dónde ir, Mozilla es una comunidad mundial de entusiastas de la web, incluyendo mentores y profesores, encantados de ayudarte. Ponte en contacto con ellos mediante WebMaker: Conoce y dialoga con los mentores y profesores en el Foro de Discusión en Español. Encuentra Eventos y aprende acerca de la Web con profesionales. Nos gustaría saber cualquier cosa de ti, si bien crees que algo está mal o falta en el sitio, o quieres solicitar nuevos temas de aprendizaje, solicitar ayuda con elementos que no comprendes o cualquier otra pregunta o inquietud que tengas.

+ +

Si estás interesado en ayudar a desarrollar/mejorar el contenido, consulta {{web.link("/es/docs/Learn/Como_Contribuir", "cómo puedes ayudar")}} y, ¡pónte en contacto!; estaremos más que felices de hablar contigo, bien seas un alumno, un maestro, un desarrollador web experimentado o alguien más, interesado en ayudar a mejorar la experiencia de aprendizaje.

+ +

Ve también

+ +
+
Boletín informativo para desarrolladores de Mozilla
+
Nuestro boletín para desarrolladores web, es un excelente recurso para todos los niveles de experiencia.
+
Aprende JavaScript
+
Un excelente recurso para los aspirantes a desarrolladores web — aprende JavaScript en un entorno interactivo, con lecciones breves y pruebas interactivas, guiado por una evaluación automatizada. Las primeras 40 lecciones son gratuitas y el curso completo está disponible por un pequeño pago único.
+
Web desmitificada
+
Una gran serie de videos que explican los fundamentos de la web, dirigida a principiantes absolutos en el desarrollo web. Creada por Jérémie Patonnier.
+
Codecademy
+
Un gran sitio interactivo para aprender lenguajes de programación desde cero.
+
BitDegree
+
Teoría básica de la codificación con un proceso de aprendizaje ludificado. Enfocado principalmente a principiantes.
+
Code.org
+
Teoría y práctica de codificación básica, principalmente dirigida a niños/principiantes.
+
EXLskills
+
Cursos gratuitos y abiertos para aprender habilidades tecnológicas, con tutorías y aprendizaje basado en proyectos.
+
freeCodeCamp.org
+
Sitio interactivo con tutoriales y proyectos para aprender desarrollo web.
+
Mapa de alfabetización web
+
Un marco de desarrollo para la alfabetización web a nivel de entrada y las habilidades del siglo XXI, que también brindan acceso a actividades de enseñanza clasificadas por categoría.
+
Edabit
+
Miles de desafíos interactivos de JavaScript.
+
diff --git a/files/es/learn/javascript/asynchronous/async_await/index.html b/files/es/learn/javascript/asynchronous/async_await/index.html new file mode 100644 index 0000000000..3487b11664 --- /dev/null +++ b/files/es/learn/javascript/asynchronous/async_await/index.html @@ -0,0 +1,411 @@ +--- +title: Haciendo la programación asíncrona más fácil con async y await +slug: Learn/JavaScript/Asynchronous/Async_await +translation_of: Learn/JavaScript/Asynchronous/Async_await +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}
+ +

Las incorporaciones más recientes al lenguaje JavaScript, son las funciones async y la palabra clave await, parte de la edición ECMAScript 2017 (véase ECMAScript Next support in Mozilla). Estas características, básicamente, actúan como azúcar sintáctico, haciendo el código asíncrono fácil de escribir y leer más tarde. Hacen que el código asíncrono se parezca más al código síncrono de la vieja escuela, por lo que merece la pena aprenderlo. 

+ +

Este artículo le da lo que usted necesita saber. 

+ + + + + + + + + + + + +
Requisitos previos:Conocimientos básicos de informática, entender de manera razonable los fundamentos de JavaScript y entender el código asíncrono en general y las promesas. 
Objetivo:Entender las promesas y cómo usarlas
+ +

Los fundamentos de async/await

+ +

Hay dos partes a la hora de usar async/await en su código.

+ +

La palabra clave async

+ +

Primero tenemos la palabra clave "async", que se coloca delante de la declaración de una función, para convertirla en función "async"(asíncrona). Una función "async", es una función que sabe cómo esperar la posibilidad de que la palabra clave "await" sea utilizada para invocar código asíncrono. 

+ +

Intenta escribir las siguientes líneas en la consola de tu navegador. 

+ +
function hello() { return "Hello" };
+hello();
+ +

La función returna "Hello" — nada especial, verdad?

+ +

Pero, qué pasa si convertimos esto en una función async? Trata lo siguiente:

+ +
async function hello() { return "Hello" };
+hello();
+ +

Ah!. Ahora cuando invocamos la función, retorna una promesa(promise). Esta es una de las características particulares de las funciones async —  los valores que retornan están garantizados para ser convertidos en promesas.

+ +

También puedes crear una expresión de función async, así:

+ +
let hello = async function() { return "Hello" };
+hello();
+ +

Y puedes utilizar funciones flecha(arrow functions):

+ +
let hello = async () => { return "Hello" };
+ +

Todos estos hacen básicamente lo mismo.

+ +

Para realmente consumir el valor retornado cuando la promesa se cumple, ya que se está devolviendo una promesa, podemos utilizar un bloque then()

+ +
hello().then((value) => console.log(value))
+ +

o incluso sólo un shorthand como

+ +
hello().then(console.log)
+ +

Como vimos en el último artículo.

+ +

La palabra clave async se añade a las funciones para decirles que devuelvan una promesa en lugar de devolver directamente el valor. Adicionamente, esto permite que las funciones síncronas eviten cualquier potencial sobrecarga que viene con correr con el soporte por usar async. Cuando una función es declarada async con sólo añadir la manipulación necesaria, el motor de JavaScript puede optimizar su programa por usted. Dulce!

+ +

So the async keyword is added to functions to tell them to return a promise rather than directly returning the value. In addition, this lets synchronous functions avoid any potential overhead that comes with running with support for using await. By only adding the necessary handling when the function is declared async, the JavaScript engine can optimize your program for you. Sweet!

+ +

La palabra clave await

+ +

La ventaja real de las funciones asincronas aparecen cuando las combinas con la palabra clave await — en efecto, await solo trabaja dentro de las funciones async. Esta puede ser puesta frente a cualquier funcion async basada en una promesa para pausar tu codigo en esa linea hasta que se cumpla la promesa, entonces retorna el valor resultante. Mientras tanto, otro código que puede estar esperando una oportunidad para ejecutarse, puede hacerlo.

+ +

Puedes usar await cuando llames cualquier funcion que retorna una Promesa, incluyendo funciones web API.

+ +

Este es un ejemplo trivial:

+ +
async function hello() {
+  return greeting = await Promise.resolve("Hello");
+};
+
+hello().then(alert);
+ +

Por supuesto, el ejemplo anterior no es muy util, aunque este sirve para ilustrar la syntaxis. Vamos a ver un ejemplo real.

+ +

Reescribiendo el código de las promesas con async/await

+ +

Let's look back at a simple fetch example that we saw in the previous article:

+ +
fetch('coffee.jpg')
+.then(response => {
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return response.blob();
+  }
+})
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

By now, you should have a reasonable understanding of promises and how they work, but let's convert this to use async/await to see how much simpler it makes things:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    let myBlob = await response.blob();
+
+    let objectURL = URL.createObjectURL(myBlob);
+    let image = document.createElement('img');
+    image.src = objectURL;
+    document.body.appendChild(image);
+  }
+}
+
+myFetch()
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

It makes code much simpler and easier to understand — no more .then() blocks everywhere!

+ +

Since an async keyword turns a function into a promise, you could refactor your code to use a hybrid approach of promises and await, bringing the second half of the function out into a new block to make it more flexible:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return await response.blob();
+  }
+}
+
+myFetch().then((blob) => {
+  let objectURL = URL.createObjectURL(blob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}).catch(e => console.log(e));
+ +

You can try typing in the example yourself, or running our live example (see also the source code).

+ +

But how does it work?

+ +

You'll note that we've wrapped the code inside a function, and we've included the async keyword before the function keyword. This is necessary — you have to create an async function to define a block of code in which you'll run your async code; as we said earlier, await only works inside of async functions.

+ +

Inside the myFetch() function definition you can see that the code closely resembles the previous promise version, but there are some differences. Instead of needing to chain a .then() block on to the end of each promise-based method, you just need to add an await keyword before the method call, and then assign the result to a variable. The await keyword causes the JavaScript runtime to pause your code on this line, allowing other code to execute in the meantime, until the async function call has returned its result. Once that's complete, your code continues to execute starting on the next line. For example:

+ +
let response = await fetch('coffee.jpg');
+ +

The response returned by the fulfilled fetch() promise is assigned to the response variable when that response becomes available, and the parser pauses on this line until that occurs. Once the response is available, the parser moves to the next line, which creates a Blob out of it. This line also invokes an async promise-based method, so we use await here as well. When the result of operation returns, we return it out of the myFetch() function.

+ +

This means that when we call the myFetch() function, it returns a promise, so we can chain a .then() onto the end of it inside which we handle displaying the blob onscreen.

+ +

You are probably already thinking "this is really cool!", and you are right — fewer .then() blocks to wrap around code, and it mostly just looks like synchronous code, so it is really intuitive.

+ +

Adding error handling

+ +

And if you want to add error handling, you've got a couple of options.

+ +

You can use a synchronous try...catch structure with async/await. This example expands on the first version of the code we showed above:

+ +
async function myFetch() {
+  try {
+    let response = await fetch('coffee.jpg');
+
+    if (!response.ok) {
+      throw new Error(`HTTP error! status: ${response.status}`);
+    } else {
+      let myBlob = await response.blob();
+      let objectURL = URL.createObjectURL(myBlob);
+      let image = document.createElement('img');
+      image.src = objectURL;
+      document.body.appendChild(image);
+    }
+  } catch(e) {
+    console.log(e);
+  }
+}
+
+myFetch();
+ +

The catch() {} block is passed an error object, which we've called e; we can now log that to the console, and it will give us a detailed error message showing where in the code the error was thrown.

+ +

If you wanted to use the second (refactored) version of the code that we showed above, you would be better off just continuing the hybrid approach and chaining a .catch() block onto the end of the .then() call, like this:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return await response.blob();
+  }
+}
+
+myFetch().then((blob) => {
+  let objectURL = URL.createObjectURL(blob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch((e) =>
+  console.log(e)
+);
+ +

This is because the .catch() block will catch errors occurring in both the async function call and the promise chain. If you used the try/catch block here, you might still get unhandled errors in the myFetch() function when it's called.

+ +

You can find both of these examples on GitHub:

+ + + +

Awaiting a Promise.all()

+ +

async/await is built on top of promises, so it's compatible with all the features offered by promises. This includes Promise.all() — you can quite happily await a Promise.all() call to get all the results returned into a variable in a way that looks like simple synchronous code. Again, let's return to an example we saw in our previous article. Keep it open in a separate tab so you can compare and contrast with the new version shown below.

+ +

Converting this to async/await (see live demo and source code), this now looks like so:

+ +
async function fetchAndDecode(url, type) {
+  let response = await fetch(url);
+
+  let content;
+
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    if(type === 'blob') {
+      content = await response.blob();
+    } else if(type === 'text') {
+      content = await response.text();
+    }
+
+    return content;
+  }
+
+}
+
+async function displayContent() {
+  let coffee = fetchAndDecode('coffee.jpg', 'blob');
+  let tea = fetchAndDecode('tea.jpg', 'blob');
+  let description = fetchAndDecode('description.txt', 'text');
+
+  let values = await Promise.all([coffee, tea, description]);
+
+  let objectURL1 = URL.createObjectURL(values[0]);
+  let objectURL2 = URL.createObjectURL(values[1]);
+  let descText = values[2];
+
+  let image1 = document.createElement('img');
+  let image2 = document.createElement('img');
+  image1.src = objectURL1;
+  image2.src = objectURL2;
+  document.body.appendChild(image1);
+  document.body.appendChild(image2);
+
+  let para = document.createElement('p');
+  para.textContent = descText;
+  document.body.appendChild(para);
+}
+
+displayContent()
+.catch((e) =>
+  console.log(e)
+);
+ +

You'll see that the fetchAndDecode() function has been converted easily into an async function with just a few changes. See the Promise.all() line:

+ +
let values = await Promise.all([coffee, tea, description]);
+ +

By using await here we are able to get all the results of the three promises returned into the values array, when they are all available, in a way that looks very much like sync code. We've had to wrap all the code in a new async function, displayContent(), and we've not reduced the code by a lot of lines, but being able to move the bulk of the code out of the .then() block provides a nice, useful simplification, leaving us with a much more readable program.

+ +

For error handling, we've included a .catch() block on our displayContent() call; this will handle errors ocurring in both functions.

+ +
+

Note: It is also possible to use a sync finally block within an async function, in place of a .finally() async block, to show a final report on how the operation went — you can see this in action in our live example (see also the source code).

+
+ +

The downsides of async/await

+ +

Async/await is really useful to know about, but there are a couple of downsides to consider.

+ +

Async/await makes your code look synchronous, and in a way it makes it behave more synchronously. The await keyword blocks execution of all the code that follows until the promise fulfills, exactly as it would with a synchronous operation. It does allow other tasks to continue to run in the meantime, but your own code is blocked.

+ +

This means that your code could be slowed down by a significant number of awaited promises happening straight after one another. Each await will wait for the previous one to finish, whereas actually what you want is for the promises to begin processing simultaneously, like they would do if we weren't using async/await.

+ +

There is a pattern that can mitigate this problem — setting off all the promise processes by storing the Promise objects in variables, and then awaiting them all afterwards. Let's have a look at some examples that prove the concept.

+ +

We've got two examples available — slow-async-await.html (see source code) and fast-async-await.html (see source code). Both of them start off with a custom promise function that fakes an async process with a setTimeout() call:

+ +
function timeoutPromise(interval) {
+  return new Promise((resolve, reject) => {
+    setTimeout(function(){
+      resolve("done");
+    }, interval);
+  });
+};
+ +

Then each one includes a timeTest() async function that awaits three timeoutPromise() calls:

+ +
async function timeTest() {
+  ...
+}
+ +

Each one ends by recording a start time, seeing how long the timeTest() promise takes to fulfill, then recording an end time and reporting how long the operation took in total:

+ +
let startTime = Date.now();
+timeTest().then(() => {
+  let finishTime = Date.now();
+  let timeTaken = finishTime - startTime;
+  alert("Time taken in milliseconds: " + timeTaken);
+})
+ +

It is the timeTest() function that differs in each case.

+ +

In the slow-async-await.html example, timeTest() looks like this:

+ +
async function timeTest() {
+  await timeoutPromise(3000);
+  await timeoutPromise(3000);
+  await timeoutPromise(3000);
+}
+ +

Here we simply await all three timeoutPromise() calls directly, making each one alert for 3 seconds. Each subsequent one is forced to wait until the last one finished — if you run the first example, you'll see the alert box reporting a total run time of around 9 seconds.

+ +

In the fast-async-await.html example, timeTest() looks like this:

+ +
async function timeTest() {
+  const timeoutPromise1 = timeoutPromise(3000);
+  const timeoutPromise2 = timeoutPromise(3000);
+  const timeoutPromise3 = timeoutPromise(3000);
+
+  await timeoutPromise1;
+  await timeoutPromise2;
+  await timeoutPromise3;
+}
+ +

Here we store the three Promise objects in variables, which has the effect of setting off their associated processes all running simultaneously.

+ +

Next, we await their results — because the promises all started processing at essentially the same time, the promises will all fulfill at the same time; when you run the second example, you'll see the alert box reporting a total run time of just over 3 seconds!

+ +

You'll have to test your code carefully, and bear this in mind if performance starts to suffer.

+ +

Another minor inconvenience is that you have to wrap your awaited promises inside an async function.

+ +

Async/await class methods

+ +

As a final note before we move on, you can even add async in front of class/object methods to make them return promises, and await promises inside them. Take a look at the ES class code we saw in our object-oriented JavaScript article, and then look at our modified version with an async method:

+ +
class Person {
+  constructor(first, last, age, gender, interests) {
+    this.name = {
+      first,
+      last
+    };
+    this.age = age;
+    this.gender = gender;
+    this.interests = interests;
+  }
+
+  async greeting() {
+    return await Promise.resolve(`Hi! I'm ${this.name.first}`);
+  };
+
+  farewell() {
+    console.log(`${this.name.first} has left the building. Bye for now!`);
+  };
+}
+
+let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
+ +

The first class method could now be used something like this:

+ +
han.greeting().then(console.log);
+ +

Browser support

+ +

One consideration when deciding whether to use async/await is support for older browsers. They are available in modern versions of most browsers, the same as promises; the main support problems come with Internet Explorer and Opera Mini.

+ +

If you want to use async/await but are concerned about older browser support, you could consider using the BabelJS library — this allows you to write your applications using the latest JavaScript and let Babel figure out what changes if any are needed for your user’s browsers. On encountering a browser that does not support async/await, Babel's polyfill can automatically provide fallbacks that work in older browsers.

+ +

Conclusion

+ +

And there you have it — async/await provide a nice, simplified way to write async code that is simpler to read and maintain. Even with browser support being more limited than other async code mechanisms at the time of writing, it is well worth learning and considering for use, both for now and in the future.

+ +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/es/learn/javascript/asynchronous/concepts/index.html b/files/es/learn/javascript/asynchronous/concepts/index.html new file mode 100644 index 0000000000..df3feb2117 --- /dev/null +++ b/files/es/learn/javascript/asynchronous/concepts/index.html @@ -0,0 +1,162 @@ +--- +title: General asynchronous programming concepts +slug: Learn/JavaScript/Asynchronous/Concepts +tags: + - Aprender + - Hilos + - JavaScript + - Promesas + - Threads + - bloques +translation_of: Learn/JavaScript/Asynchronous/Concepts +--- +
{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}
+ +

En este artículo, repasaremos una serie de conceptos importantes relacionados con la programación asincrónica y cómo se ve esto en los navegadores web y JavaScript. Debe comprender estos conceptos antes de trabajar con los demás artículos del módulo.

+ + + + + + + + + + + + +
Pre-requisitos:Literatura básica de computadora, un razonable entendimiento de los fundamentos de JavaScript.
Objetivo:Entender los conceptos básicos detrás de la programación asincrónica, y cómo se manifiesta en los exploradores web y JavaScript.
+ +

¿Asincrónico?

+ +

Normalmente, el código de un programa determinado se ejecuta directamente, y solo sucede una cosa a la vez. Si una función se basa en el resultado de otra función, tiene que esperar a que la otra función termine y regrese, y hasta que eso suceda, todo el programa se detiene esencialmente desde la perspectiva del usuario.

+ +

Los usuarios de Mac, por ejemplo, a veces experimentan esto como un cursor giratorio multicolor (o "beachball" - "bola de playa" - como es llamado frecuentemente). Este cursor es la manera que tiene el sistema operativo de decir "el actual programa que está usando tiene que parar y esperar que algo termine, y está tomando tanto tiempo que me preocupa que pienses qué está sucediendo."

+ +

Multi-colored macOS beachball busy spinner

+ +

Esto es una experiencia frustrante y no es un buen uso del poder de procesamiento de una computadora - especialmente en una era donde las computadoras tienen múltiples procesadores disponibles. No tiene sentido sentarse allí a esperar algo cuando podrías dejar que la otra tarea se ejecute en otro procesador y le notifique cuando termine. Mientras tanto, esto le permitiría terminar otros trabajos, lo cual es la base de la programación asincrónica. Depende del entorno de programación que esté usando (exploradores web, en caso de desarrollo web) proveer de APIs que le permitan ejecutar dichas tareas de manera asincrónica.

+ +

Código de bloqueo (Blocking)

+ +

Las técnicas asincrónicas son muy útiles, particularmente en programación web. Cuando una app web se ejeucta en el navegador y ejecuta un gran bloque de código sin retornar el control al navegador, este mismo puede parecer que se congela. Esto es llamado blocking; el navegador es bloqueado para que el usuario pueda seguir interactuando y realizando otras tareas hasta que la app web retorne el control sobre el procesador.

+ +

Vamos a ver algunos ejemplos que muestren lo que significa blocking.

+ +

En nuestro ejemplo simple-sync.html (véalo en vivo), agregamos un detector del evento click ("click event listener") a un botón con el fin de que cuando sea clickeado, ejecute una operación de un gran consumo de tiempo (calcula 10 millones de fechas y luego muestra la última en la consola) y luego agrega un párrafo al DOM:

+ +
const btn = document.querySelector('button');
+btn.addEventListener('click', () => {
+  let myDate;
+  for(let i = 0; i < 10000000; i++) {
+    let date = new Date();
+    myDate = date
+  }
+
+  console.log(myDate);
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'This is a newly-added paragraph.';
+  document.body.appendChild(pElem);
+});
+ +

Cuando ejecute el ejemplo, abra su consola de JavaScript y haga click en el botón — notará que el párrafo no aparece hasta que las fechas hayan sido calculadas en su totalidad y el mensaje en la consola haya sido logueado. EL código se ejecuta en el orden en que aparece (de arriba hacia abajo), y la última operación no se ejecuta hasta que la anterior haya terminado.

+ +
+

Nota: El ejemplo anterior es poco realista. ¡Nunca se van a calcular 10 millones de fechas en una app web real! Sin embargo, sirve para dar una idea básica.

+
+ +

En nuestro segundo ejemplo, simple-sync-ui-blocking.html (véalo en vivo), se simula algo un poco más realista con el que se puede encontrar en una página real. Se bloquea la interacción del usuario con la carga ("rendering") de la UI. En este ejemplo, se tienen dos botones:

+ + + +
function expensiveOperation() {
+  for(let i = 0; i < 1000000; i++) {
+    ctx.fillStyle = 'rgba(0,0,255, 0.2)';
+    ctx.beginPath();
+    ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
+    ctx.fill()
+  }
+}
+
+fillBtn.addEventListener('click', expensiveOperation);
+
+alertBtn.addEventListener('click', () =>
+  alert('You clicked me!')
+);
+ +

Si se clickea el primer botón y rápidamente se clickea el segundo, se verá que la alerta no aparece hasta que los círculos hayan terminado de representarse. La primer operación blockea a la segunda hasta que esta haya terminado de ejecutarse.

+ +
+

Nota: OK, nuestro caso es feo y estamos fingiendo el efecto de bloqueo, pero es un problema común con el que los desarrolladores de aplicaciones reales batallan todo el tiempo.

+
+ +

¿Por qué es esto? La respuesta es porque JavaScript, en general, es de "un solo hilo" (single-threaded). En este punto, se tiene que introduce el concepto de "hilos" (threads).

+ +

Threads

+ +

Un hilo (thread) es básicamente un proceso simple que un programa puede usar para completar tareas ("tasks"). Cada hilo solo puede realizar una tarea a la vez:

+ +
Task A --> Task B --> Task C
+ +

Cada tarea se va a ejecutar secuencialmente; una tarea tiene que completarse antes de que la próxima empiece.

+ +

Como se dijo previamente, muchas computadores actualmente tienen múltiples procesadores, por lo que pueden realizar múltiples tareas a la vez. Los lenguajes de programación que pueden manejar múltiples hilos pueden usar múltiples procesadores para completar múltiples tareas en simultáneo. 

+ +
Thread 1: Task A --> Task B
+Thread 2: Task C --> Task D
+ +

JavaScript es single-threaded

+ +

JavScript es tradicionalmente single-threaded. Aún con múltiples procesadores, solo se puede ejecutar tareas en un solo hilo, llamado el hilo principal (main thread). El ejemplo de arriba se ejecuta de la siguiente manera:

+ +
Main thread: Render circles to canvas --> Display alert()
+ +

Después de un tiempo, JavaScript ganó algunas herramientas que ayudaron con dichos problemas. Web workers permiten que se envíe parte del procesamiento de JavaScript a un hilo separado, llamado worker con el fin de que puedan ejecutar múltiples pedazos de JavaScript en simultáneo. Generalmente se usará un worker para ejectuar procesos de mucho consumo del hilo principal (main thread) con el fin de que no se bloquee la interacción del usuario.

+ +
  Main thread: Task A --> Task C
+Worker thread: Expensive task B
+ +

Con esto en mente, miremos el ejemplo simple-sync-worker.html (véalo ejecutándose en vivo) nuevamente con la consola de JavaScript del navegador abierta. Esto es una re-escritura del ejemplo anterior que calculaba 10 millones de fechas en hilos worker separados. Ahora si se clickea el botón, el navegador tiene permitido mostrar el párrafo antes de que las fechas haya terminado de calcularse. La primer operación ya no bloquea a la segunda.

+ +

Código asincrónico

+ +

Los web workers son muy útiles, pero tienen limitaciones. La mayor es que no pueden acceder al {{Glossary("DOM")}} — no se puede logar que un worker modifique directamente algo de la UI. No se puede representar 1 millón de círculos azules en un worker; básicamente solo puede hacer el cálculo numérico.

+ +

El segundo problema es que a pesar de que el código se ejecuta en un worker no es bloqueador, es simplemente sincrónico. Esto se convierte en un problema cuando una función depender en los resultados de múltiples procesos previos para funcionar. Considere el siguiente diagrama de hilos:

+ +
Main thread: Task A --> Task B
+ +

En este caso, digamos que la Tarea A (Task A) está haciendo algo como buscando una imagen de un servidor y la Tarea B (Task B) luego hace algo con la imagen, como aplicarle un filtro. Si se ejecuta la Tarea A y luego inmediatamente se trata de ejecutar la Tarea B, se obtendrá un error, porque la imagen todavía no estará disponible.

+ +
  Main thread: Task A --> Task B --> |Task D|
+Worker thread: Task C -----------> |      |
+ +

En este caso, digamos que la Tarea D hace uso de los resultados de la Tarea B y la Tarea C. Se se puede garantizar que esos resultados estarán disponibles al mismo tiempo, entonces tal vez estemos OK, pero es poco probable. Si la Tarea D trata de ejecutarse cuando uno de sus inputs no está disponible, disparará un error.

+ +

Para arreglar dichos problemas, los navegadores nos permiten ejecutar ciertas operaciones asincrónicamente. Características como las Promises (Promesas) permiten establecer la ejecución de una operación (por ejemplo, buscar una imagen desde un servidor), y luego esperar hasta que el resultado sea retornado antes de ejecutar otra operación. 

+ +
Main thread: Task A                   Task B
+    Promise:      |__async operation__|
+ +

Como la operación está sucediendo en otro lugar, el hilo principal no está bloqueado mientras la operación asincrónica está siendo procesada.

+ +

Vamos a empezar a ver cómo se puede escribir código asincrónico en el próximo artículo. Cosas emocionantes, ¿eh? ¡Siga leyendo!

+ +

Conclusión

+ +

El diseño del software moderno gira cada más entorno a la programación asincrónica, para permiterle a los programas hacer más de una cosa a la vez. A medida que use nuevas y más poderosas APIs, encontrará más casos donde la única forma de realizar las cosas es asincrónicamente. Era muy difícil escribir el código asincrónico. Todavía lleva tiempo acostumbrarse, pero se ha vuelto mucho más sencillo. En el resto de este módulo, exploraremos porqué el código asincrónico importa y cómo diseñar código que evite algunos de los problemas que hemos descrito en este artículo.

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/asynchronous/index.html b/files/es/learn/javascript/asynchronous/index.html new file mode 100644 index 0000000000..b2fb697803 --- /dev/null +++ b/files/es/learn/javascript/asynchronous/index.html @@ -0,0 +1,43 @@ +--- +title: JavaScript asíncrono +slug: Learn/JavaScript/Asynchronous +translation_of: Learn/JavaScript/Asynchronous +--- +
{{LearnSidebar}}
+ +

En este módulo echamos un vistazo a {{Glossary("JavaScript")}} {{Glossary("asíncrono")}}, por qué es importante y cómo se puede utilizar para manejar eficazmente las posibles operaciones de bloqueo, como recuperar recursos desde un servidor

+ +

Prerrequisitos

+ +

JavaScript asíncrono es un tema bastante avanzado, y se recomienda trabajar con los primeros pasos de JavaScript y los módulos de bloques de construcción de JavaScript antes de intentarlo.

+ +

Si no está familiarizado con el concepto de programación asincrónica, definitivamente debe comenzar con el artículo Conceptos generales de programación asincrónica en este módulo. Si es así, probablemente pueda pasar al módulo Introducción a JavaScript asíncrono.

+ +
+

Nota: Si está trabajando en una computadora / tableta / otro dispositivo donde no tiene la capacidad de crear sus propios archivos, puede probar (la mayoría de) los ejemplos de código en un programa de codificación en línea como JSBin o Glitch

+
+ +

Guias

+ +
+
Conceptos generales de programación asincrónica
+
+

En este artículo revisaremos una serie de conceptos importantes relacionados con la programación asincrónica y cómo se ve esto en los navegadores web y JavaScript. Debe comprender estos conceptos antes de trabajar en los otros artículos del módulo.

+
+
Introduciendo JavaScript asincrónico
+
En este artículo recapitulamos brevemente los problemas asociados con JavaScript síncrono, y echamos un primer vistazo a algunas de las diferentes técnicas de JavaScript asíncrono que encontrarás, mostrando cómo pueden ayudarnos a resolver tales problemas.
+
JavaScript asíncrono cooperativo: tiempos de espera e intervalos
+
Aquí observamos los métodos tradicionales que JavaScript tiene disponibles para ejecutar código de forma asíncrona después de que haya transcurrido un período de tiempo establecido, o en un intervalo regular (por ejemplo, un número establecido de veces por segundo), hablemos sobre para qué son útiles y observe su Problemas inherentes.
+
Manejo de operaciones asincrónas con Promises
+
Las promesas son una característica relativamente nueva de JavaScript que le permite diferir más acciones hasta que la acción anterior se haya completado o responder en caso de tener una falla o error durante su ejecución. Esto es realmente útil para configurar una secuencia de operaciones para que funcione correctamente. Este artículo te muestra cómo funcionan las promesas, dónde las verá en uso en una WebAPI y cómo escribir las tuyas de la manera adecuada.
+
Hacer la programación asincróna más fácil con async y await 
+
Las promesas pueden ser algo complejas de configurar y comprender, por lo que los navegadores modernos han implementado funciones async y el operador de await. El primero permite que las funciones estándar se comporten implícitamente de forma asíncrona con las promesas, mientras que el segundo puede usarse dentro de las funciones async para esperar las promesas antes de que la función continúe. Esto hace que las promesas de encadenamiento sean más simples y fáciles de leer.
+
Elegir el enfoque correcto
+
Para finalizar este módulo, consideraremos las diferentes técnicas y características de codificación que hemos discutido a lo largo de todo, y veremos cuáles deberias usar cuando, con recomendaciones y recordatorios de dificultades comunes, sea lo más apropiado.
+
+ +

Ver también

+ + diff --git a/files/es/learn/javascript/building_blocks/bucle_codigo/index.html b/files/es/learn/javascript/building_blocks/bucle_codigo/index.html new file mode 100644 index 0000000000..e26509afc5 --- /dev/null +++ b/files/es/learn/javascript/building_blocks/bucle_codigo/index.html @@ -0,0 +1,923 @@ +--- +title: Bucles +slug: Learn/JavaScript/Building_blocks/Bucle_codigo +translation_of: Learn/JavaScript/Building_blocks/Looping_code +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}
+ +

Los lenguajes de programación son muy útiles para completar rápidamente tareas repetitivas, desde múltimples cálculos básicos hasta cualquier otra situación en donde tengas un montón de elementos de trabajo similares que completar. Aquí vamos a ver las estructuras de bucles disponibles en JavaScript que pueden manejar tales necesidades.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de computación, entendimiento básico de HTML y CSS, JavaScript first steps.
Objetivo:Entender cómo usar bucles en JavaScript.
+ +

Mantente en el Bucle

+ +

Bucles, bucles, bucles. Además de ser conocidos como un cereal de desayuno popular, montañas rusas y producción músical, también son un concepto muy importante en programación. Los bucles de programación están relacionados con todo lo referente a hacer una misma cosa una y otra vez — que se denomina como iteración en el idioma de programación.

+ +

Consideremos el caso de un agricultor que se asegura de tener suficiente comida para alimentar a su familia durante la semana. Podría usar el siguiente bucle para lograr esto:

+ +


+

+ +

Un bucle cuenta con una o más de las siguientes características:

+ + + +

En {{glossary("pseudocódigo")}},esto se vería como sigue:

+ +
bucle(comida = 0; comidaNecesaria = 10) {
+  if (comida = comidaNecesaria) {
+    salida bucle;
+    // Tenemos suficiente comida; vamonos para casa
+  } else {
+    comida += 2; // Pasar una hora recogiendo 2 más de comida
+    // Comenzar el bucle de nuevo
+  }
+}
+ +

Así que la cantidad necesaria de comida se establece en 10, y la cantidad incial del granjero en 0. En cada iteración del bucle comprobamos si la cantidad de comida del granjero es mayor o igual a la cantidad que necesita. Si lo es, podemos salir del bucle. Si no, el granjero se pasará una hora más recogiendo dos porciones de comida, y el bucle arrancará de nuevo.

+ +

¿Por qué molestarse?

+ +

En este punto, probablemente entiendas los conceptos de alto nivel que hay detrás de los bucles, pero probablemente estés pensando "OK, fantástico, pero ¿cómo me ayuda esto a escribir un mejor codigo JavaScript?". Como dijimos antes, los bucles tienen que ver con hacer lo mismo una y otra vez, lo cual es bueno para completar rápidamente tareas repetitivas.

+ +

Muchas veces, el código será ligeramente diferente en cada iteracción sucesiva del bucle, lo que significa que puedes completar una carga completa de tareas que son similares, pero ligeramente diferentes — si tienes muchos calculos diferentes que hacer, quieres hacer cada uno de ellos, ¡no el mismo una y otra vez!

+ +

Vamos a ver un ejemplo para ilustrar perfectamente por qué los bucles son tan útiles. Digamos que queremos dibujar 100 círculos aleatorios en un elemento {{htmlelement("canvas")}} (presiona el botón Update para ejecutar el ejemplo una y otra vez y ver diferentes configuraciones aleatorias):

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }}

+ +

No tienes que entender todo el código por ahora, pero vamos a echar un vistazo a la parte de código que dibuja los 100 círculos:

+ +
for (var i = 0; i < 100; i++) {
+  ctx.beginPath();
+  ctx.fillStyle = 'rgba(255,0,0,0.5)';
+  ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+  ctx.fill();
+}
+ +

Debes quedarte con la idea básica.  — utilizamos un bucle para ejecutar 100 iteracciones de este código, cada una de las cuales dibuja un círculo en una posición aleatoria de la página. La cantidad de código necesario sería el mismo si dibujáramos 100, 1000, o 10,000 círculos. Solo necesitamos cambiar un número.

+ +

Si no usáramos un bucle aquí, tendríamos que repetir el siguiente código por cada círculo que quisiéramos dibujar:

+ +
ctx.beginPath();
+ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ctx.fill();
+ +

Esto sería muy aburrido y difícil de mantener de forma rápida. Los bucles son realmente lo mejor.

+ +

El bucle estándar for

+ +

Exploremos algunos constructores de bucles específicos. El primero, que usarás la mayoría de las veces, es el bucle for - este tiene la siguiente sintaxis:

+ +
for (inicializador; condición de salida; expresión final) {
+  // código a ejecutar
+}
+ +

Aquí tenemos:

+ +
    +
  1. La palabra reservada for, seguida por algunos paréntesis.
  2. +
  3. Dentro de los paréntesis tenemos tres ítems, separados por punto y coma (;): +
      +
    1. Un inicializador - Este es usualmente una variable con un número asignado, que aumenta el número de veces que el bucle ha sijo ejecutado. También se le llama contador o variable de conteo.
    2. +
    3. Una condición de salida - como se mencionó previamente, ésta define cuando el bucle debería detenerse. Generalmente es una expresión que contiene un operador de comparación, una prueba para verificar ue la condición de término o salida ha sido cumplida.
    4. +
    5. Una expresión final - que es siempre evaluada o ejecutada cada vez que el bucle ha completado una iteración. Usualmente sirve para modificar al contador (incrementando su valor o algunas veces disminuyendolo), para aproximarse a la condición de salida.
    6. +
    +
  4. +
  5. Algunos corchetes curvos que contienen un bloque de código - este código se ejecutará cada vez que se repita el bucle.
  6. +
+ +

Observa un ejemplo real para poder entender esto más claramente.

+ +
var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin'];
+var info = 'My cats are called ';
+var para = document.querySelector('p');
+
+for (var i = 0; i < cats.length; i++) {
+  info += cats[i] + ', ';
+}
+
+para.textContent = info;
+ +

Esto nos da el siguiente resultado:

+ + + +

{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Nota: Puedes encontrar este ejemplo de código en GitHub también (además puedes verlo ejecutar en vivo).

+
+ +

Esto muestra un bucle siendo usado para iterar sobre los elementos de un arreglo (matriz), y hacer algo con cada uno de ellos - un patrón muy común en JavaScript. Aquí:

+ +
    +
  1. El iterador, i, inicia en 0 (var i = 0).
  2. +
  3. Se le ha dicho que debe ejecutarse hasta que no sea menor que la longitud del arreglo cats. Esto es importante  - la condición de salida muestra la condicion bajo la cual el bucle seguirá iterando. Así, en este caso, mientras i < cats.length sea verdadero, el bucle seguirá ejecutándose.
  4. +
  5. Dentro del bucle, concatenamos el elemento del bucle actual (cats[i] es cats[lo que sea i en ese momento]) junto con una coma y un espacio, al final de la variable info. Así: +
      +
    1. Durante la primera ejecución,  i = 0, así cats[0] + ', ' se concatenará con la información ("Bill, ").
    2. +
    3. Durante la segunda ejecución, i = 1, así cats[1] + ', ' agregará el siguiente nombre ("Jeff, ").
    4. +
    5. Y así sucesivamente. Después de cada vez que se ejecute el bucle, se incrementará en 1 el valod de i (i++), entonces el proceso comenzará de nuevo.
    6. +
    +
  6. +
  7. Cuando i sea igual a cats.length, el bucle se detendrá, y el navegador se moverá al siguiente segmento de código bajo el bucle.
  8. +
+ +
+

Nota: Hemos programado la condición de salidad como i < cats.length, y no como i <= cats.length, porque los computadores cuentan desde 0, no 1 - inicializamos la variable i en 0, para llegar a i = 4 (el índice del último elemento del arreglo). cats.length responde 5, ya que existen 5 elementos en el arreglo, pero no queremos que i = 5, dado que respondería undefined para el último elemento (no existe un elemento en el arreglo con un índice 5). for the last item (there is no array item with an index of 5). Por ello, queremos llegar a 1 menos que cats.length (i <), que no es lo mismo que cats.length (i <=).

+
+ +
+

Nota: Un error común con la condición de salida es utilizar el comparador "igual a" (===) en vez de "menor o igual a" (<=). Si queremos que nuestro bucle se ejecute hasta que  i = 5, la condición de salida debería ser i <= cats.length. Si la declaramos i === cats.length, el bucle no debería ejecutarse , porque i no es igual a 5 en la primera iteración del bucle, por lo que debería detenerse inmediatamente.

+
+ +

Un pequeño problema que se presenta es que la frase de salida final no está muy bien formada:

+ +
+

My cats are called Bill, Jeff, Pete, Biggles, Jasmin,

+
+ +

Idealmente querríamos cambiar la concatenacion al final de la última iteracion del bucle, así no tendríamos una coma en el final de la frase. Bueno, no hay problema - podemos insertar un condicional dentro de nuestro bucle para solucionar este caso especial:

+ +
for (var i = 0; i < cats.length; i++) {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+}
+ +
+

Note: You can find this example code on GitHub too (also see it running live).

+
+ +
+

Importante: Con for - como con todos los bucles - debes estar seguro de que el inicializador es repetido hasta que eventualemtne alcance la condición de salida. Si no, el bucle seguirá repitiéndose indefinidamente, y puede que el navegador lo fuerce a detenerse o se interrumpa. Esto se denomina bucle infinito.

+
+ +

Salir de un bucle con break

+ +

Si deseas salir de un bucle antes de que se hayan completado todas las iteraciones, puedes usar la declaración break. Ya la vimos en el artículo previo cuando revisamos la declaración switch - cuando un caso en una declaración switch coincide con la expresión de entrada, la declaración break inmediatamente sale de la declaración switch y avanza al código que se encuentra después.

+ +

Ocurre lo mismo con los bucles - una declaración break saldrá inmediatamente del bucle y hará que el navegador siga con el código que sigue después.

+ +

Digamos que queremos buscar a través de un arreglo de contactos y números telefónicos y retornar sólo el número que queríamos encontrar. primero, un simple HTML -  un {{htmlelement("input")}} de texto que nos permita ingresar un nombre para buscar, un elemento {{htmlelement("button")}} para enviar la búsqueda, y un elemento {{htmlelement("p")}} para mostrar el resultado:

+ +
<label for="search">Search by contact name: </label>
+<input id="search" type="text">
+<button>Search</button>
+
+<p></p>
+ +

Ahora en el JavaScript:

+ +
var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975'];
+var para = document.querySelector('p');
+var input = document.querySelector('input');
+var btn = document.querySelector('button');
+
+btn.addEventListener('click', function() {
+  var searchName = input.value;
+  input.value = '';
+  input.focus();
+  for (var i = 0; i < contacts.length; i++) {
+    var splitContact = contacts[i].split(':');
+    if (splitContact[0] === searchName) {
+      para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.';
+      break;
+    } else {
+      para.textContent = 'Contact not found.';
+    }
+  }
+});
+ + + +

{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. First of all we have some variable definitions — we have an array of contact information, with each item being a string containing a name and phone number separated by a colon.
  2. +
  3. Next, we attach an event listener to the button (btn), so that when it is pressed, some code is run to perform the search and return the results.
  4. +
  5. We store the value entered into the text input in a variable called searchName, before then emptying the text input and focusing it again, ready for the next search.
  6. +
  7. Now onto the interesting part, the for loop: +
      +
    1. We start the counter at 0, run the loop until the counter is no longer less than contacts.length, and increment i by 1 after each iteration of the loop.
    2. +
    3. Inside the loop we first split the current contact (contacts[i]) at the colon character, and store the resulting two values in an array called splitContact.
    4. +
    5. We then use a conditional statement to test whether splitContact[0] (the contact's name) is equal to the inputted searchName. If it is, we enter a string into the paragraph to report what the contact's number is, and use break to end the loop.
    6. +
    +
  8. +
  9. If the contact name does not match the entered search, the paragraph text is set to "Contact not found.", and the loop continues iterating.
  10. +
+ +
+

Note: You can view the full source code on GitHub too (also see it running live).

+
+ +

Skipping iterations with continue

+ +

The continue statement works in a similar manner to break, but instead of breaking out of the loop entirely, it skips to the next iteration of the loop. Let's look at another example that takes a number as an input, and returns only the numbers that are squares of integers (whole numbers).

+ +

The HTML is basically the same as the last example — a simple text input, and a paragraph for output. The JavaScript is mostly the same too, although the loop itself is a bit different:

+ +
var num = input.value;
+
+for (var i = 1; i <= num; i++) {
+  var sqRoot = Math.sqrt(i);
+  if (Math.floor(sqRoot) !== sqRoot) {
+    continue;
+  }
+
+  para.textContent += i + ' ';
+}
+ +

Here's the output:

+ + + +

{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. In this case, the input should be a number (num). The for loop is given a counter starting at 1 (as we are not interested in 0 in this case), an exit condition that says the loop will stop when the counter becomes bigger than the input num, and an iterator that adds 1 to the counter each time.
  2. +
  3. Inside the loop, we find the square root of each number using Math.sqrt(i), then check whether the square root is an integer by testing whether it is the same as itself when it has been rounded down to the nearest integer (this is what Math.floor() does to the number it is passed).
  4. +
  5. If the square root and the rounded down square root do not equal one another (!==), it means that the square root is not an integer, so we are not interested in it. In such a case, we use the continue statement to skip on to the next loop iteration without recording the number anywhere.
  6. +
  7. If the square root IS an integer, we skip past the if block entirely so the continue statement is not executed; instead, we concatenate the current i value plus a space on to the end of the paragraph content.
  8. +
+ +
+

Note: You can view the full source code on GitHub too (also see it running live).

+
+ +

while and do ... while

+ +

for is not the only type of loop available in JavaScript. There are actually many others and, while you don't need to understand all of these now, it is worth having a look at the structure of a couple of others so that you can recognize the same features at work in a slightly different way.

+ +

First, let's have a look at the while loop. This loop's syntax looks like so:

+ +
initializer
+while (exit-condition) {
+  // code to run
+
+  final-expression
+}
+ +

This works in a very similar way to the for loop, except that the initializer variable is set before the loop, and the final-expression is included inside the loop after the code to run — rather than these two items being included inside the parentheses. The exit-condition is included inside the parentheses, which are preceded by the while keyword rather than for.

+ +

The same three items are still present, and they are still defined in the same order as they are in the for loop — this makes sense, as you still have to have an initializer defined before you can check whether it has reached the exit-condition; the final-condition is then run after the code inside the loop has run (an iteration has been completed), which will only happen if the exit-condition has still not been reached.

+ +

Let's have a look again at our cats list example, but rewritten to use a while loop:

+ +
var i = 0;
+
+while (i < cats.length) {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+
+  i++;
+}
+ +
+

Note: This still works just the same as expected — have a look at it running live on GitHub (also view the full source code).

+
+ +

The do...while loop is very similar, but provides a variation on the while structure:

+ +
initializer
+do {
+  // code to run
+
+  final-expression
+} while (exit-condition)
+ +

In this case, the initializer again comes first, before the loop starts. The do keyword directly precedes the curly braces containing the code to run and the final-expression.

+ +

The differentiator here is that the exit-condition comes after everything else, wrapped in parentheses and preceded by a while keyword. In a do...while loop, the code inside the curly braces is always run once before the check is made to see if it should be executed again (in while and for, the check comes first, so the code might never be executed).

+ +

Let's rewrite our cat listing example again to use a do...while loop:

+ +
var i = 0;
+
+do {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+
+  i++;
+} while (i < cats.length);
+ +
+

Note: Again, this works just the same as expected — have a look at it running live on GitHub (also view the full source code).

+
+ +
+

Important: With while and do...while — as with all loops — you must make sure that the initializer is iterated so that it eventually reaches the exit condition. If not, the loop will go on forever, and either the browser will force it to stop, or it will crash. This is called an infinite loop.

+
+ +

Active learning: Launch countdown!

+ +

In this exercise, we want you to print out a simple launch countdown to the output box, from 10 down to Blast off. Specifically, we want you to:

+ + + +

If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.

+ + + +

{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}

+ +

Active learning: Filling in a guest list

+ +

In this exercise, we want you to take a list of names stored in an array, and put them into a guest list. But it's not quite that easy — we don't want to let Phil and Lola in because they are greedy and rude, and always eat all the food! We have two lists, one for guests to admit, and one for guests to refuse.

+ +

Specifically, we want you to:

+ + + +

We've already provided you with:

+ + + +

Extra bonus question — after completing the above tasks successfully, you will be left with two lists of names, separated by commas, but they will be untidy — there will be a comma at the end of each one. Can you work out how to write lines that slice the last comma off in each case, and add a full stop to the end? Have a look at the Useful string methods article for help.

+ +

If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.

+ + + +

{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}

+ +

Which loop type should you use?

+ +

For basic uses, for, while, and do...while loops are largely interchangeable. They can all be used to solve the same problems, and which one you use will largely depend on your personal preference — which one you find easiest to remember or most intuitive. Let's have a look at them again.

+ +

First for:

+ +
for (initializer; exit-condition; final-expression) {
+  // code to run
+}
+ +

while:

+ +
initializer
+while (exit-condition) {
+  // code to run
+
+  final-expression
+}
+ +

and finally do...while:

+ +
initializer
+do {
+  // code to run
+
+  final-expression
+} while (exit-condition)
+ +

We would recommend for, at least to begin with, as it is probably the easiest for remembering everything — the initializer, exit-condition, and final-expression all have to go neatly into the parentheses, so it is easy to see where they are and check that you aren't missing them.

+ +
+

Note: There are other loop types/features too, which are useful in advanced/specialized situations and beyond the scope of this article. If you want to go further with your loop learning, read our advanced Loops and iteration guide.

+
+ +

Conclusion

+ +

This article has revealed to you the basic concepts behind, and different options available when, looping code in JavaScript. You should now be clear on why loops are a good mechanism for dealing with repetitive code, and be raring to use them in your own examples!

+ +

If there is anything you didn't understand, feel free to read through the article again, or contact us to ask for help.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}

+ +

In this module

+ + +<gdiv></gdiv> diff --git a/files/es/learn/javascript/building_blocks/conditionals/index.html b/files/es/learn/javascript/building_blocks/conditionals/index.html new file mode 100644 index 0000000000..7a0fdcb91d --- /dev/null +++ b/files/es/learn/javascript/building_blocks/conditionals/index.html @@ -0,0 +1,778 @@ +--- +title: Tomando decisiones en tu código — condicionales +slug: Learn/JavaScript/Building_blocks/conditionals +tags: + - Aprendizaje + - Artículo + - Codificación + - Condicionales + - JavaScript + - Principiante +translation_of: Learn/JavaScript/Building_blocks/conditionals +--- +
+

{{LearnSidebar}}

+ +

{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}

+
+ +

En cualquier lenguaje de programación, el código necesita realizar decisiones y llevar a cabo diferentes acciones acordes dependiendo de distintas entradas. Por ejemplo, en un juego, si el el numero de vidas del jugador es 0, entonces se termina el juego. En una aplicación del clima, si se observa en la mañana, se despliega una gráfica del amanecer; muestra estrellas y una luna si es de noche. En este artículo, exploraremos cómo las llamadas declaraciones condicionales funcionan en JavaScript.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de informática, básico entendimiento de HTML y CSS, JavaScript primeros pasos.
Objetivo:Entender como se usan las extructuras condicionales en JavaScript. 
+ +

Puedes hacerlo en una condición..!

+ +

Los seres humanos (y otros animales) toman decisiones todo el tiempo que afectan sus vidas, desde la más insignificante ("¿Debería comer una galleta o dos?") hasta la más grande (¿Debería quedarme en mi país y trabajar en la granja de mi padre, o debería mudarme a Estados Unidos y estudiar astrofísica?). 

+ +

+ +

Declaraciones if ... else 

+ +

Echemos un vistazo a la declaración condicional más común que usarás en JavaScript.

+ +

 — El humilde if ... else statement.

+ +

Sintaxis if ... else básica. 

+ +

Una sintaxis básica if...else luce así. {{glossary("pseudocode")}}:

+ +
if (condición) {
+  código a ejecutar si la condición es verdadera
+} else {
+  ejecuta este otro código si la condición es falsa
+}
+ +

Aquí tenemos:

+ +
    +
  1. La palabra clave if seguida de unos paréntesis.
  2. +
  3. Una condición a probar, puesta dentro de los paréntesis (típicamente "¿es este valor mayor que este otro valor?", o "¿existe este valor?"). Esta condición usará los  operadores de comparación que hemos hablado en el módulo anterior y retorna un valor true o false (verdadero o falso).
  4. +
  5. Un conjunto de llaves, en las cuales tenemos algún código — puede ser cualquier código que deseemos, código que se ejecutará sólamente si la condición retorna true.
  6. +
  7. La palabra clave else.
  8. +
  9. Otro conjunto de llaves, dentro de las cuales tendremos otro código — puede ser cualquier código que deseemos, y sólo se ejecutará si la condición no es true.
  10. +
+ +

Este código es fácil de leer —  está diciendo "si (if)  la condición retorna verdadero (true),  entonces ejecute el código A, sino (else)  ejecute el código B"

+ +

Habrás notado que no tienes que incluir else y el segundo bloque de llaves — La siguiente declaración también es perfectmaente legal. 

+ +
if (condición) {
+  ejecuta el código de al ser verdadera la condición
+}
+
+ejecuta otro código
+ +

Sin embargo, hay que ser cuidadosos — en este caso, el segundo bloque no es controlado por una declaración condicional, así que siempre se ejecutará, sin importar si la condicional devuelve true o false. Esto no es necesariemente algo malo, pero puede ser algo que no quieras —  a menudo desearás ejecutar un bloque de código u otro, no ambos.

+ +

Como punto final, habrán ocaciones donde veas delcaraciones  if...else escritas sin un conjunto de llaves, de esta manera:

+ +
if (condición) ejecuta código de ser verdadero (true)
+else ejecuta este otro código 
+ +

Este código es perfectamente valido, pero no es recomendado usarlo — es mucho más fácil leer el código y determinar qué sucede haciendo uso de  las llaves para delimitar los bloques de código y usar varias líneas y sangrías.

+ +

Un ejemplo real

+ +

Para comprender mejor la sintaxis,  realicemos un ejemplo real. Imagínese a un niño a quien su madre o padre le pide ayuda con una tarea. El padre podría decir: "¡Hola, cariño! Si me ayudas yendo y haciendo las compras, te daré un subsidio adicional para que puedas pagar ese juguete que querías". En JavaScript, podríamos representar esto así:

+ +
let compraRealizada = false;
+
+if (compraRealizada === true) {
+  let subsidioAdicional = 10;
+} else {
+  let subsidioAdicional = 5;
+}
+ +

La variable compraRealizada escrita en este código dará siempre como resultado un retorno de valor  false,  lo cuál significa una desilusión para nuestro pobre hijo. Depende de nosotros proporcionar un mecanismo para que el padre cambie el valor de la variable compraRealizadatrue si el niño realizó la compra.

+ +
+

Nota: Podrás ver una versión más completa de este ejemplo en GitHub (también podrás verlo corriendo en vivo.)

+
+ +

else if

+ +

El último ejemplo nos proporcionó dos opciones o resultados, pero ¿qué ocurre si queremos más de dos?

+ +

Hay una forma de encadenar  opciones / resultados adicionales extras a if...else — usando else if. Cada opción extra requiere un bloque adicional para poner en medio de bloque if() { ... } y else { ... } — Vea el siguiente ejemplo un poco más complicado, que podría ser parte de una aplicación para un simple pronóstico del tiempo:

+ +
<label for="clima">Seleccione el tipo de clima de hoy: </label>
+<select id="clima">
+  <option value="">--Haga una elección--</option>
+  <option value="soleado">Soleado</option>
+  <option value="lluvioso">Lluvioso</option>
+  <option value="nevando">Nevando</option>
+  <option value="nublado">Nublado</option>
+</select>
+
+<p></p>
+ +
let seleccionar = document.querySelector('select');
+let parrafo = document.querySelector('p');
+
+seleccionar.addEventListener('change', establecerClima);
+
+function establecerClima() {
+  let eleccion = seleccionar.value;
+
+  if (eleccion === 'soleado') {
+    parrafo.textContent = 'El día esta agradable y soleado hoy. ¡Use pantalones cortos! Ve a la playa o al parque y come un helado.';
+  } else if (eleccion === 'lluvioso') {
+    parrafo.textContent = 'Está lloviendo, tome un abrigo para lluvia y un paraguas, y no se quede por fuera mucho tiempo.';
+  } else if (eleccion === 'nevando') {
+    parrafo.textContent = 'Está nevando ─ ¡está congelando! Lo mejor es quedarse en casa con una taza caliente de chocolate, o hacer un muñeco de nieve.';
+  } else if (eleccion === 'nublado') {
+    parrafo.textContent = 'No está lloviendo, pero el cielo está gris y nublado; podría llover en cualquier momento, así que lleve un saco solo por si acaso.';
+  } else {
+    parrafo.textContent = '';
+  }
+}
+
+
+ +

{{ EmbedLiveSample('else_if', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. Aquí tenemos un elemento HTML {{htmlelement("select")}} que nos permite realizar varias elecciones sobre el clima, y un parrafo simple.
  2. +
  3. En el JavaScript, estamos almacenando una referencia para ambos elementos {{htmlelement("select")}} y {{htmlelement("p")}} , y añadiendo un Event Listener o en español un Detector de Eventos al elemento <select>  así cuando su valor cambie se ejecuta la función establecerClima().
  4. +
  5. Cuando la función es ejecutada, primero establecemos la variable eleccion con el valor obtenido del elemento <select>. Luego usamos una declaración condicinal  para mostrar distintos textos dentro del párrafo {{htmlelement("p")}} dependiendo del valor de la variable eleccion. Note  como todas las condicinales son probadas en los bloques else if() {...} , a excepción del primero, el cual es probado en el primer bloque if() {...}.
  6. +
  7. La ultima elección,  dentro del bloque else {...}, es básicamente  el "último recurso" como opción—  El código dentro de este bloque se ejecutará si nunguna de las condiciones es true. En este caso, sirve para vaciar el contenido del párrafo si nada ha sido seleccionado, por ejemplo, si el usuario decide elegir de nuevo  "--Haga una elección--" mostrado al inicio.
  8. +
+ +
+

Nota: Puedes encontrar  este ejemplo en GitHub (También podrás verlo correr en vivo.)

+
+ +

Una nota en los operadores de comparación 

+ +

Los operadores de comparación son usados para probar las condiciones dentro de nuestra declaración condicional. Vimos estos operadores en el artículo Matématica básica en JavaScript — Números y operadores. Nuestras opciones son:

+ + + +
+

Nota: Revisa el material en los enlaces previos para refrescar la memoria en estos temas. 

+
+ +

Queremos hacer una mención especial al probar los valores  (true/false) , y un patrón común que te encontrarás una y otra vez. Cualquier valor que no sea false, undefined, null, 0, NaN,  o una cadena vacía string ('') realmente retorna el valor true cuando es probada como una declaración condicional, por lo tanto puedes simplemente usar el nombre de una variable para probar si es  true, o si al menos existe  (i.e. no está definido.) Por ejemplo:

+ +
let queso = 'Cheddar';
+
+if (queso) {
+  console.log('¡Siii! Hay queso para hacer tostadas con queso.');
+} else {
+  console.log('No hay tostadas con queso para ti hoy :(.');
+}
+ +

En el ejemplo anterior la variable queso contiene el valor 'Cheddar', y como su valor está definido o no es false, undefined, null, 0, NaN y (' ') es considerado como true lo cual hará mostrar el mensaje dentro del primer bloque de llaves. 

+ +

Y, devolviéndonos al ejemplo previo del niño haciendo las compras para su padre, lo podrías haber escrito así:

+ +
let compraRealizada = false;
+
+if (compraRealizada) { //no necesitas especificar explícitamente '=== true'
+   let subsidioAdicional = 10;
+} else {
+   let subsidioAdicional = 5;
+}
+ +

Anidando if ... else

+ +

Está perfectamente permitido poner una declaración  if...else dentro de otra declaración if...else —  para anidarlas. Por ejemplo, podemos actualizar nuestra aplicación del clima para mostrar una serie de opciones dependiendo de cual sea la temperatura:

+ +
if (elección === 'soleado') {
+  if (temperatura < 86) {
+    parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — agradable y soleado. Vamos a la playa, o al parque, y comer helado.';
+  } else if (temperatura >= 86) {
+    parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — ¡QUÉ CALOR! Si deseas salir, asegúrate de aplicarte bloqueador solar.';
+  }
+}
+ +

Aunque el código funciona en conjunto, cada declaración  if...else funciona complentamente independiente del otro.

+ +

Operadores lógicos: AND, OR y NOT

+ +

Si quieres probar multiples condiciones sin escribir declaraciones  if...else anidados,  los operadores lógicos  pueden ayudarte. Cuando se usa en condiciones, los primeros dos hacen lo siguiente:

+ + + +

Para poner un ejemplo de  AND, el anterior código puede ser reescrito de esta manera:

+ +
if (eleccion === 'soleado' && temperatura < 86) {
+  parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — agradable y soleado. Vamos a la playa, o al parque, y comer helado.';
+} else if (eleccion === 'soleado' && temperatura >= 86) {
+  parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — ¡QUÉ CALOR! Si deseas salir, asegúrate de aplicarte bloqueador solar.';
+}
+ +

Así que por ejemplo, el primer bloque solo se ejecutará si la variable eleccion === 'soleado' temperatura < 86 devuelven un valor verdadero o true.

+ +

Observemos un ejemplo rápido del operador OR:

+ +
if (carritoDeHelados || estadoDeLaCasa === 'en llamas') {
+  console.log('Debes salir de la casa rápidamente.');
+} else {
+  console.log('Es mejor que te quedes dentro de casa');
+}
+ +

El último tipo de operador lógico, NOT, es expresado con el operador !, puede ser usado para negar una expresión. Vamos a combinarlo con el operador OR en el siguiente ejemplo:

+ +
if (!(carritoDeHelados || estadoDeLaCasa === 'en llamas')) {
+  console.log('Es mejor que te quedes dentro de casa');
+} else {
+  console.log('Debes salir de la casa rápidamente.');
+}
+ +

En el anterior ejemplo, si las declaraciones del operador OR retornan un valor true,  el operador NOT negará toda la expresión dentro de los paréntesis, por lo tanto retornará un valor false.

+ +

Puedes combinar los operadores que quieras dentro de las sentencias, en cualquier estructura. El siguiente ejemplo ejecuta el código dentro del condicional solo si ambas sentencias OR devuelven verdadero, lo que significa que la instrucción general AND devolverá verdadero:

+ +
if ((x === 5 || y > 3 || z <= 10) && (logueado || nombreUsuario === 'Steve')) {
+  // ejecuta el código
+}
+ +

Un error comun cuando se utiliza el operador OR en las declaraciones condicionales es intentar verificar el valor de la variable una sola vez, y luego darle una lista de valores que podrían retornar verdadero separados por  operadores ||. Por ejemplo:

+ +
if (x === 5 || 7 || 10 || 20) {
+  // ejecuta mi código
+}
+ +

En este caso la condición  if(...)  siempre evaluará a verdadero siendo que  7 (u otro valor que no sea 0) siempre será verdadero. Esta condición lo que realmente está diciendo es que "if x es igual a 5, o 7 es verdadero— lo cual siempre es". ¡Esto no es lógicamente lo que queremos!  Para hacer que esto funcione, tenemos que especificar una prueba completa para cada lado del operador OR:

+ +
if (x === 5 || x === 7 || x === 10 ||x === 20) {
+  // ejecuta mi código
+}
+ +

Declaraciones con switch

+ +

El condicional if...else hace un buen trabajo permitiéndonos realizar un buen código, pero esto viene con sus desventajas.  Hay variedad de casos donde necesitarás realizar varias elecciones, y cada una requiere una cantidad razonable de código para ser ejecutado y/o sus condicionales son complejas (i.e. operadores lógicos múltiples). Para los casos en los que solo se desea establecer una variable para una determinada opción de valores o imprimir una declaración particular dependiendo de una condición, la sintaxis puede ser un poco engorrosa, especialmente si se tiene una gran cantidad de opciones.

+ +

Para estos casos los switch statements son de gran ayuda — toman una sola expresión / valor como una entrada, y luego pasan a través de una serie de opciones hasta que encuentran una que coincida con ese valor, ejecutando el código correspondiente que va junto con ella. Aquí hay un pseudocódigo más para hacerte una idea:

+ +
switch (expresion) {
+  case choice1:
+    ejecuta este código
+    break;
+
+  case choice2:
+    ejecuta este código
+    break;
+
+  // Se pueden incluir todos los casos que quieras
+
+  default:
+    por si acaso, corre este código
+}
+ +

Aquí tenemos:

+ +
    +
  1. La palabra clave switch, seguida por un conjunto de paréntesis.
  2. +
  3. Una expresión o valor dentro de los paréntesis.
  4. +
  5. La palabra clave case, seguida de una elección con la expresión / valor que podría ser, seguido de dos puntos.
  6. +
  7. Algún código a correr si la elección coincide con la expresión.
  8. +
  9. Un declaración llamada break,  seguida de un punto y coma. Si la elección previa coincide con la expresión / valor, el explorador dejará de ejecutar el bloque de código aquí, y continuará a la siguiente línea de código. Si la opción anterior coincide con la expresión / valor, aquí el navegador deja de ejecutar el bloque de código  y pasa a cualquier código que aparezca debajo de la declaración de switch.
  10. +
  11. Como muchos otros casos, los que quieras.
  12. +
  13. La palabra clave default, seguido exactamente del mismo patrón de código que en los casos anteriores , excepto que el valor predeterminado no tiene opciónes después de él, y no es necesario que se use break porque no hay nada que ejecutar después de este bloque de todas formas. Esta es la opción predeterminada o por defecto que se ejecuta si ninguna de las opciones coincide.
  14. +
+ +
+

Nota: No tiene que incluir la sección default; se puede omitir con seguridad si no hay posibilidades de que la expresión  termine igualando un valor desconocido. Sin embargo, si existe la posibilidad de que esto ocurra, debe incluirlo para evitar casos desconocidos o comportamientos extraños en tu código.

+
+ +

Un ejemplo con switch

+ +

Let's have a look at a real example — we'll rewrite our weather forecast application to use a switch statement instead:

+ +
<label for="weather">Select the weather type today: </label>
+<select id="weather">
+  <option value="">--Make a choice--</option>
+  <option value="sunny">Sunny</option>
+  <option value="rainy">Rainy</option>
+  <option value="snowing">Snowing</option>
+  <option value="overcast">Overcast</option>
+</select>
+
+<p></p>
+ +
let select = document.querySelector('select');
+let para = document.querySelector('p');
+
+select.addEventListener('change', setWeather);
+
+
+function setWeather() {
+  let choice = select.value;
+
+  switch (choice) {
+    case 'sunny':
+      para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.';
+      break;
+    case 'rainy':
+      para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.';
+      break;
+    case 'snowing':
+      para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.';
+      break;
+    case 'overcast':
+      para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.';
+      break;
+    default:
+      para.textContent = '';
+  }
+}
+ +

{{ EmbedLiveSample('A_switch_example', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Nota: Tambien puedes encontrar este ejemplo en GitHub (tambien puedes verlo en ejecución aquí.)

+
+ +

Operador Ternario

+ +

Hay una última sintaxis que queremos presentarte antes de que juegues con algunos ejemplos. El operador ternario o condicional es una pequeña sintaxis que prueba una condición y devuelve un valor/expresión, si es true, y otro si es false — Esto puede ser útil en algunas situaciones, y puede ocupar mucho menos código que un bloque if...else si simplemente tienes dos opciones que se eligen a través de una condición true/false. El pseudocódigo se ve así:

+ +
( condición ) ? ejecuta este código : ejecuta este código en su lugar
+ +

Veamos un ejemplo simple:

+ +
let greeting = ( isBirthday ) ? 'Happy birthday Mrs. Smith — we hope you have a great day!' : 'Good morning Mrs. Smith.';
+ +

Aquí tenemos una variable llamada isBirthday — si esta es true, le damos a nuestro invitado un mensaje de feliz cumpleaños; si no, le damos el saludo diario estándar.

+ +

Ejemplo con operador ternario

+ +

No solo puedes establecer valores variables con el operador ternario; También puedes ejecutar funciones o líneas de código — lo que quieras. El siguiente ejemplo muestra un selector de tema simple donde el estilo del sitio se aplica utilizando un operador ternario.

+ +
<label for="theme">Select theme: </label>
+<select id="theme">
+  <option value="white">White</option>
+  <option value="black">Black</option>
+</select>
+
+<h1>This is my website</h1>
+ +
let select = document.querySelector('select');
+let html = document.querySelector('html');
+document.body.style.padding = '10px';
+
+function update(bgColor, textColor) {
+  html.style.backgroundColor = bgColor;
+  html.style.color = textColor;
+}
+
+select.onchange = function() {
+  ( select.value === 'black' ) ? update('black','white') : update('white','black');
+}
+
+ +

{{ EmbedLiveSample('Ternary_operator_example', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Aquí tenemos un elemento {{htmlelement('select')}} para elegir un tema (blanco o negro), más un simple (black or white), plus a simple {{htmlelement('h1')}} para mostrar el título de un sitio web. También tenemos una función llamada update(), que toma dos colores como parámetros (entradas). El color de fondo del sitio web se establece en el primer color proporcionado y el color del texto se establece en el segundo color proporcionado.

+ +

Finalmente, también tenemos un detector de eventos onchange que sirve para ejecutar una función que contiene un operador ternario. Comienza con una condición de prueba — select.value === 'black'. Si esto devuelve true, ejecutamos la función update() con parámetros de blanco y negro, lo que significa que terminamos con un color de fondo negro y un color de texto blanco. Si devuelve false, ejecutamos las función update() con parámetros de blanco y negro, lo que significa que el color del sitio está invertido.

+ +
+

Nota: También puedes encontrar este ejemplo en GitHub (y verlo en ejecución aquí.)

+
+ +

Aprendizaje activo: Un calendario simple

+ +

En este ejemplo, nos ayudará a terminar una aplicación de calendario simple. En el código tienes:

+ + + +

Necesitamos que escriba una declaración condicional dentro de la función del controlador onchange justo debajo del comentario // ADD CONDITIONAL HERE. Debería:

+ +
    +
  1. Mire el mes seleccionado (almacenado en la variable choice. Este será el valor del elemento <select> después de que cambie el valor, por ejemplo "January")
  2. +
  3. Establezca una variable llamada days para que sea igual al número de días del mes seleccionado. Para hacer esto, tendrá que buscar el número de días en cada mes del año. Puede ignorar los años bisiestos a los efectos de este ejemplo.
  4. +
+ +

Sugerencias:

+ + + +

Si comete un error, siempre puede restablecer el ejemplo con el botón "Reset". Si se queda realmente atascado, presione "Show solution" para ver una solución.

+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 1110, "", "", "hide-codepen-jsfiddle") }}

+ +

Aprendizaje activo: Más opciones de colores!

+ +

In this example, you are going to take the ternary operator example we saw earlier and convert the ternary operator into a switch statement that will allow us to apply more choices to the simple website. Look at the {{htmlelement("select")}} — this time you'll see that it has not two theme options, but five. You need to add a switch statement just underneath the // ADD SWITCH STATEMENT comment:

+ + + +

If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.

+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 950, "", "", "hide-codepen-jsfiddle") }}

+ +

Conclusión

+ +

And that's all you really need to know about conditional structures in JavaScript right now! I'm sure you'll have understood these concepts and worked through the examples with ease; if there is anything you didn't understand, feel free to read through the article again, or contact us to ask for help.

+ +

Revisa también

+ + + +

{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html b/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html new file mode 100644 index 0000000000..5f9bcc7c8b --- /dev/null +++ b/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html @@ -0,0 +1,252 @@ +--- +title: Construye tu propia función +slug: Learn/JavaScript/Building_blocks/Construyendo_tu_propia_funcion +tags: + - Aprender + - Artículo + - Construir + - Funciones + - Guía + - JavaScript + - Principiante + - Tutorial +translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}
+ +

Con la mayor parte de la teoría esencial tratada en el artículo anterior, este artículo proporciona experiencia práctica. Aquí obtendrás práctica construyendo tu propia función personalizada. En el camino, también explicaremos algunos detalles útiles sobre cómo tratar las funciones.

+ + + + + + + + + + + + +
Prerequisites:Conocimientos básicos de computación, una comprensión básica de HTML y CSS, JavaScript first steps, Functions — reusable blocks of code.
Objective:Para proporcionar algo de práctica en la construcción de una función personalizada, y explicar algunos detalles asociados más útiles.
+ +

Aprendizaje activo: construyamos una función.

+ +

La función personalizada que vamos a construir se llamará displayMessage(). Mostrará un cuadro de mensaje personalizado en una página web y actuará como un reemplazo personalizado para la función de alert() incorporada de un navegador. Hemos visto esto antes, pero solo refresquemos nuestros recuerdos. Escriba lo siguiente en la consola de JavaScript de su navegador, en la página que desee:

+ +
alert('This is a message');
+ +

La función alert tiene un argumento — el string que se muestra en la alerta. Prueba a variar el string para cambiar el mensaje.

+ +

La función alert es limitada: pueder cambiar el mensaje, pero no puedes cambiar de manera sencilla nada más, como el color, icono o cualquier otra cosa. Construiremos uno que resultará ser más divertido.

+ +
+

Nota: Este ejemplo debería funcionar bien en todos los navegadores modernos, pero el estilo puede parecer un poco divertido en los navegadores un poco más antiguos. Te recomendamos que hagas este ejercicio en un navegador moderno como Firefox, Opera o Chrome.

+
+ +

La función básica

+ +

Para empezar, vamos a poner juntos una función básica.

+ +
+

Nota: Para las convenciones de nombres de las funciones, debes seguir las mismas reglas que convecion de nombres de variables. Esto está bien, ya que puede distinguirlos: los nombres de las funciones aparecen entre paréntesis después de ellos y las variables no.

+
+ +
    +
  1. Comience accediendo al archivo function-start.html y haciendo una copia local. Verás que el HTML es simple  — el body unicamente tiene un botón. También hemos propocionado algunos estilos básicos de CSS para customizar el mensaje y un elemento  {{htmlelement("script")}} vacío para poner nuestro JavaScript dentro.
  2. +
  3. Luego añade lo siguiente dentro del elemento <script>: +
    function displayMessage() {
    +
    +}
    + Comenzamos con la palabra clave función, lo que significa que estamos definiendo una función. A esto le sigue el nombre que queremos darle a nuestra función, un conjunto de paréntesis y un conjunto de llaves. Todos los parámetros que queremos darle a nuestra función van dentro de los paréntesis, y el código que se ejecuta cuando llamamos a la función va dentro de las llaves.
  4. +
  5. Finalmente, agregue el siguiente código dentro de las llaves: +
    let html = document.querySelector('html');
    +
    +let panel = document.createElement('div');
    +panel.setAttribute('class', 'msgBox');
    +html.appendChild(panel);
    +
    +let msg = document.createElement('p');
    +msg.textContent = 'This is a message box';
    +panel.appendChild(msg);
    +
    +let closeBtn = document.createElement('button');
    +closeBtn.textContent = 'x';
    +panel.appendChild(closeBtn);
    +
    +closeBtn.onclick = function() {
    +  panel.parentNode.removeChild(panel);
    +}
    +
  6. +
+ +

Esto es un montón de código por el que pasar, así que lo guiaremos paso a paso.

+ +

La primera línea usa un función DOM API llamada {{domxref("document.querySelector()")}} para seleccionar el elemento {{htmlelement("html")}} y guardar una referencia a él en una variable llamada html, por lo que podemos hacer cosas para más adelante:

+ +
let html = document.querySelector('html');
+ +

La siguiente sección usa otra función del DOM API llamada {{domxref("Document.createElement()")}} para crear un elemento {{htmlelement("div")}} y guardar una referencia a él en una variable llamada panel. Este elemento será el contenedor exterior de nuestro cuadro de mensaje.

+ +

Entonces usamos otra función del API DOM llamada {{domxref("Element.setAttribute()")}} para configurar un atributo a class en nuestro panel con un valor de msgBox. Esto es para facilitar el estilo del elemento. — Si echas un vistazo al CSS en la página, verás que estamos utilizando un selector de clases.msgBox para dar estilo al al contenedor del mensaje.

+ +

Finalmente, llamamos a una función del DOM llamada {{domxref("Node.appendChild()")}} en la variable html que hemos guardado anteriormente, que anida un elemento dentro del otro como hijo de él. Hemos especificado el panel <div> como el hijo que queremos añadir dentro del elemento <html>. Debemos hacer esto ya que el elemento que creamos no aparecerá en la página por sí solo — tenemos que especificar donde ponerlo.

+ +
let panel = document.createElement('div');
+panel.setAttribute('class', 'msgBox');
+html.appendChild(panel);
+ +

Las siguientes dos secciones hacen uso de las mismas funciones createElement()appendChild() que ya vimos para crear dos nuevos elementos — un {{htmlelement("p")}} y un {{htmlelement("button")}} — e insertarlo en la página como un hijo del panel <div>. Usamos su propiedad  {{domxref("Node.textContent")}} — que representa el contenido de texto de un elemento: para insertar un mensaje dentro del párrafo y una 'x' dentro del botón. Este botón será lo que necesita hacer clic / activar cuando el usuario quiera cerrar el cuadro de mensaje.

+ +
let msg = document.createElement('p');
+msg.textContent = 'This is a message box';
+panel.appendChild(msg);
+
+let closeBtn = document.createElement('button');
+closeBtn.textContent = 'x';
+panel.appendChild(closeBtn);
+ +

Finalmente, usamos el manejador de evento {{domxref("GlobalEventHandlers.onclick")}} para hacerlo de modo que cuando se haga clic en el botón, se ejecute algún código para eliminar todo el panel de la página, para cerrar el cuadro de mensaje.

+ +

Brevemente, el handler onclick es una propiedad disponible en el botón (o, de hecho, en cualquier elemento de la página) que se puede configurar en una función para especificar qué código ejecutar cuando se hace clic en el botón. Aprenderás mucho más sobre esto en nuestro artículo de eventos posteriores. Estamos haciendo el handler onclick igual que una función anónima, que contiene el código para ejecutar cuando se ha hecho click en el botón. La línea dentro de la función usa la función del DOM API {{domxref("Node.removeChild()")}}  para especificar que queremos eliminar un elemento secundario específico del elemento HTML— en este caso el panel <div>.

+ +
closeBtn.onclick = function() {
+  panel.parentNode.removeChild(panel);
+}
+ +

Básicamente, todo este bloque de código está generando un bloque de HTML que se ve así, y lo está insertando en la página:

+ +
<div class="msgBox">
+  <p>This is a message box</p>
+  <button>x</button>
+</div>
+ +

Fue un montón de código con el que trabajar: ¡no te preocupes demasiado si no recuerdas exactamente cómo funciona todo ahora! La parte principal en la que queremos centrarnos aquí es la estructura y el uso de la función, pero queríamos mostrar algo interesante para este ejemplo.

+ +

Llamando a la función

+ +

Ahora tienes la definición de tu función escrita en tu elemento <script> bien, pero no hará nada tal como está.

+ +
    +
  1. Intente incluir la siguiente línea debajo de su función para llamarla: +
    displayMessage();
    + Esta línea invoca la función, haciéndola correr inmediatamente. Cuando guarde el código y lo vuelva a cargar en el navegador, verá que el pequeño cuadro de mensaje aparece inmediatamente, solo una vez. Después de todo, solo lo llamamos una vez.
  2. +
  3. +

    Ahora abra las herramientas de desarrollo de su navegador en la página de ejemplo, vaya a la consola de JavaScript y escriba la línea nuevamente allí, ¡verá que aparece nuevamente! Así que esto es divertido: ahora tenemos una función reutilizable que podemos llamar en cualquier momento que queramos.

    + +

    Pero probablemente queremos que aparezca en respuesta a las acciones del usuario y del sistema. En una aplicación real, tal cuadro de mensaje probablemente se llamará en respuesta a la disponibilidad de nuevos datos, a un error, al usuario que intenta eliminar su perfil ("¿está seguro de esto?"), O al usuario que agrega un nuevo contacto y la operación completando con éxito ... etc.

    + +

    En esta demostración, obtendremos el cuadro de mensaje que aparecerá cuando el usuario haga clic en el botón.

    +
  4. +
  5. Elimina la línea anterior que agregaste.
  6. +
  7. A continuación, seleccionaremos el botón y guardaremos una referencia a él en una variable. Agregue la siguiente línea a su código, encima de la definición de la función: +
    let btn = document.querySelector('button');
    +
  8. +
  9. Finalmente, agregue la siguiente línea debajo de la anterior: +
    btn.onclick = displayMessage;
    + De una forma similar que nuestra línea dentro de la función closeBtn.onclick..., aquí estamos llamando a algún código en respuesta a un botón al hacer clic. Pero en este caso, en lugar de llamar a una función anónima que contiene algún código, estamos llamando directamente a nuestro nombre de función.
  10. +
  11. Intente guardar y actualizar la página: ahora debería ver aparecer el cuadro de mensaje cuando hace clic en el botón.
  12. +
+ +

Quizás te estés preguntando por qué no hemos incluido los paréntesis después del nombre de la función. Esto se debe a que no queremos llamar a la función inmediatamente, solo después de hacer clic en el botón. Si intentas cambiar la línea a

+ +
btn.onclick = displayMessage();
+ +

y al guardar y volver a cargar, verás que aparece el cuadro de mensaje sin hacer clic en el botón. Los paréntesis en este contexto a veces se denominan "operador de invocación de función". Solo los utiliza cuando desea ejecutar la función inmediatamente en el ámbito actual. Del mismo modo, el código dentro de la función anónima no se ejecuta inmediatamente, ya que está dentro del alcance de la función.

+ +

Si has intentado el último experimento, asegúrate de deshacer el último cambio antes de continuar.

+ +

Mejora de la función con parámetros.

+ +

Tal como está, la función aún no es muy útil, no queremos mostrar el mismo mensaje predeterminado cada vez. Mejoremos nuestra función agregando algunos parámetros, permitiéndonos llamarla con algunas opciones diferentes.

+ +
    +
  1. En primer lugar, actualice la primera línea de la función: +
    function displayMessage() {
    + to this: + +
    function displayMessage(msgText, msgType) {
    + Ahora, cuando llamamos a la función, podemos proporcionar dos valores variables dentro de los paréntesis para especificar el mensaje que se mostrará en el cuadro de mensaje y el tipo de mensaje que es.
  2. +
  3. Para utilizar el primer parámetro, actualiza la siguiente línea dentro de su función: +
    msg.textContent = 'This is a message box';
    + to + +
    msg.textContent = msgText;
    +
  4. +
  5. Por último, pero no menos importante, ahora necesita actualizar su llamada de función para incluir un texto de mensaje actualizado. Cambia la siguiente línea: +
    btn.onclick = displayMessage;
    + to this block: + +
    btn.onclick = function() {
    +  displayMessage('Woo, this is a different message!');
    +};
    + Si queremos especificar parámetros dentro de paréntesis para la función a la que estamos llamando, no podemos llamarla directamente, necesitamos colocarla dentro de una función anónima para que no esté en el ámbito inmediato y, por lo tanto, no se llame de inmediato. Ahora no se llamará hasta que se haga clic en el botón.
  6. +
  7. Vuelva a cargar e intenta el código nuevamente y verás que aún funciona bien, ¡excepto que ahora también puede variar el mensaje dentro del parámetro para obtener diferentes mensajes mostrados en el cuadro!
  8. +
+ +

Un parámetro más complejo.

+ +

En el siguiente parámetro. Este va a implicar un poco más de trabajo: lo configuraremos de modo que, dependiendo de la configuración del parámetro msgType, la función mostrará un icono diferente y un color de fondo diferente.

+ +
    +
  1. En primer lugar, descargue los iconos necesarios para este ejercicio (warningchat) de GitHub. Guárdalos en una nueva carpeta llamada icons en la misma localización que tu HTML. + +
    Nota: los iconos warningchat que se encuentran en iconfinder.com, han sido diseñados por Nazarrudin Ansyari. Gracias!
    +
  2. +
  3. A continuación, encuentra el CSS dentro de tu archivo HTML. Haremos algunos cambios para dar paso a los iconos. Primero, actualiza el ancho de .msgBox desde: +
    width: 200px;
    + to + +
    width: 242px;
    +
  4. +
  5. Luego, añade las siguientes líneas dentro de la regla.msgBox p { ... }: +
    padding-left: 82px;
    +background-position: 25px center;
    +background-repeat: no-repeat;
    +
  6. +
  7. Ahora necesitamos añadir código a la función displayMessage() para manejar la visualización de los iconos. Agrega el siguiente bloque justo encima de la llave de cierre (}) de tu función : +
    if (msgType === 'warning') {
    +  msg.style.backgroundImage = 'url(icons/warning.png)';
    +  panel.style.backgroundColor = 'red';
    +} else if (msgType === 'chat') {
    +  msg.style.backgroundImage = 'url(icons/chat.png)';
    +  panel.style.backgroundColor = 'aqua';
    +} else {
    +  msg.style.paddingLeft = '20px';
    +}
    +
  8. +
  9. Aquí, si el parámetro msgType se establece como 'warning', se muestra el icono de advertencia y el color de fondo del panel se establece en rojo. Si se establece en 'chat', se muestra el icono de chat y el color de fondo del panel se establece en azul aguamarina. Si el parámetro msgType no está configurado en absoluto (o en algo diferente), entonces la parte else { ... } del código entra en juego, y al párrafo simplemente se le da un relleno predeterminado y ningún icono, sin el conjunto de colores del panel de fondo ya sea. Esto proporciona un estado predeterminado si no se proporciona ningún parámetro msgType , lo que significa que es un parámetro opcional.
  10. +
  11. Vamos a probar nuestra función actualizada , prueba a actualizar la llamada a displayMessage() con esto: +
    displayMessage('Woo, this is a different message!');
    + to one of these: + +
    displayMessage('Your inbox is almost full — delete some mails', 'warning');
    +displayMessage('Brian: Hi there, how are you today?','chat');
    + Puedes ver cuán útil se está volviendo nuestra (ahora no tan) poca función.
  12. +
+ +
+

Nota: Si estas teniendo problemas con el ejemplo, sientente libre para coger el ejemplo para trabajar con él, finished version on GitHub (see it running live también), o pídenos ayuda.

+
+ +

Conclusión

+ +

¡Felicidades por llegar al final! Este artículo lo llevó a través de todo el proceso de creación de una función personalizada y práctica, que con un poco más de trabajo podría trasplantarse en un proyecto real. En el siguiente artículo resumiremos las funciones explicando otro concepto esencial relacionado: valores de retorno.

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/building_blocks/eventos/index.html b/files/es/learn/javascript/building_blocks/eventos/index.html new file mode 100644 index 0000000000..7bdb81768a --- /dev/null +++ b/files/es/learn/javascript/building_blocks/eventos/index.html @@ -0,0 +1,578 @@ +--- +title: Introducción a eventos +slug: Learn/JavaScript/Building_blocks/Eventos +translation_of: Learn/JavaScript/Building_blocks/Events +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}
+ +

Los eventos son acciones u ocurrencias que suceden en el sistema que está programando y que el sistema le informa para que pueda responder de alguna manera si lo desea. Por ejemplo, si el usuario hace clic en un botón en una página web, es posible que desee responder a esa acción mostrando un cuadro de información. En este artículo, discutiremos algunos conceptos importantes que rodean los eventos y veremos cómo funcionan en los navegadores. Este no será un estudio exhaustivo; solo lo que necesitas saber en esta etapa.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, entendimiento básico de HTML y CSS, Primeros pasos con JavaScript.
Objetivo:Comprender la teoría fundamental de los eventos, cómo funcionan en los navegadores y cómo los eventos pueden diferir en distintos entornos de programación.
+ +

Una serie de eventos afortunados

+ +

Como se mencionó anteriormente, los eventos son acciones u ocurrencias que suceden en el sistema que está programando — el sistema disparará una señal de algún tipo cuando un evento ocurra y también proporcionará un mecanismo por el cual se puede tomar algún tipo de acción automáticamente (p.e., ejecutando algún código) cuando se produce el evento. Por ejemplo, en un aeropuerto cuando la pista está despejada para que despegue un avión, se comunica una señal al piloto y, como resultado, comienzan a pilotar el avión.

+ +

+ +

En el caso de la Web, los eventos se desencadenan dentro de la ventana del navegador y tienden a estar unidos a un elemento específico que reside en ella — podría ser un solo elemento, un conjunto de elementos, el documento HTML cargado en la pestaña actual o toda la ventana del navegador. Hay muchos tipos diferentes de eventos que pueden ocurrir, por ejemplo:

+ + + +

Se deducirá de esto (y echar un vistazo a MDN Referencia de eventos) que hay muchos eventos a los que se puede responder.

+ +

Cada evento disponible tiene un controlador de eventos, que es un bloque de código (generalmente una función JavaScript definida por el usuario) que se ejecutará cuando se active el evento. Cuando dicho bloque de código se define para ejecutarse en respuesta a un disparo de evento, decimos que estamos registrando un controlador de eventos. Tenga en cuenta que los controladores de eventos a veces se llaman oyentes de eventos — son bastante intercambiables para nuestros propósitos, aunque estrictamente hablando, trabajan juntos. El oyente escucha si ocurre el evento y el controlador es el código que se ejecuta en respuesta a que ocurra.

+ +
+

Nota: Es útil tener en cuenta que los eventos web no son parte del lenguaje central de JavaScript: se definen como parte de las API integradas en el navegador.

+
+ +

Un ejemplo simple

+ +

Veamos un ejemplo simple para explicar lo que queremos decir aquí. Ya has visto eventos y controladores de eventos en muchos de los ejemplos de este curso, pero vamos a recapitular solo para consolidar nuestro conocimiento. En el siguiente ejemplo, tenemos un solo {{htmlelement ("button")}}, que cuando se presiona, hará que el fondo cambie a un color aleatorio:

+ +
<button>Cambiar color</button>
+ + + +

El JavaScript se ve así:

+ +
const btn = document.querySelector('button');
+
+function random(number) {
+  return Math.floor(Math.random() * (number+1));
+}
+
+btn.onclick = function() {
+  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

En este código, almacenamos una referencia al botón dentro de una variable llamada btn, usando la función {{domxref ("Document.querySelector ()")}}. También definimos una función que devuelve un número aleatorio. La tercera parte del código es el controlador de eventos. La variable btn apunta a un elemento <button>, y este tipo de objeto tiene una serie de eventos que pueden activarse y, por lo tanto, los controladores de eventos están disponibles. Estamos escuchando el disparo del evento "click", estableciendo la propiedad del controlador de eventos onclick para que sea igual a una función anónima que contiene código que generó un color RGB aleatorio y establece el <body> color de fondo igual a este.

+ +

Este código ahora se ejecutará cada vez que se active el evento "click" en el elemento <button>, es decir, cada vez que un usuario haga clic en él.

+ +

El resultado de ejemplo es el siguiente:

+ +

{{ EmbedLiveSample('A_simple_example', '100%', 200, "", "", "hide-codepen-jsfiddle") }}

+ +

No son solo páginas web

+ +

Otra cosa que vale la pena mencionar en este punto es que los eventos no son particulares de JavaScript — la mayoría de los lenguajes de programación tienen algún tipo de modelo de eventos, y la forma en que funciona a menudo diferirá de la forma en que funciona en JavaScript. De hecho, el modelo de eventos en JavaScript para páginas web difiere del modelo de eventos para JavaScript, ya que se utiliza en otros entornos.

+ +

Por ejemplo, Node.js es un entorno en tiempo de ejecución de JavaScript muy popular que permite a los desarrolladores usar JavaScript para crear aplicaciones de red y del lado del servidor. El modelo de eventos de Node.js se basa en que los oyentes (listeners) escuchen eventos y los emisores (emitters) emitan eventos periódicamente — no suena tan diferentes, pero el código es bastante diferente, haciendo uso de funciones como on() para registrar un oyente de eventos, y once() para registrar un oyente de eventos que anula el registro después de que se haya ejecutado una vez. The documentos de eventos de conexión HTTP proporcionan un buen ejemplo de uso.

+ +

Como otro ejemplo, ahora también puede usar JavaScript para crear complementos de navegadores — mejoras de funcionalidad del navegador — utilizando una tecnología llamada WebExtensions. El modelo de eventos es similar al modelo de eventos web, pero un poco diferente — las propiedades de los oyentes de eventos se escriben en camel-case (ej. onMessage en lugar de onmessage), y deben combinarse con la función addListener. Consulte la página runtime.onMessage para ver un ejemplo.

+ +

No necesita comprender nada sobre otros entornos en esta etapa de su aprendizaje; solo queríamos dejar en claro que los eventos pueden diferir en diferentes entornos de programación.

+ +

Diferentes formas de uso de eventos

+ +

Hay muchas maneras distintas en las que puedes agregar event listeners a los sitios web, que se ejecutara cuando el evento asociado se dispare. En esta sección, revisaremos los diferentes mecanismos y discutiremos cuales deberias usar..

+ +

Propiedades de manejadores de eventos

+ +

Estas son las propiedades que existen, que contienen codigo de manejadores de eventos(Event Handler)  que vemos frecuentemente durante el curso.. Volviendo al ejemplo de arriba:

+ +
var btn = document.querySelector('button');
+
+btn.onclick = function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

La propiedad onclick es la propiedad del manejador de eventos que está siendo usada en esta situación. Es escencialmente una propiedad como cualquier otra disponible en el botón (por ejemplo: btn.textContent, or btn.style), pero es de un tipo especial — cuando lo configura para ser igual a algún código, ese código se ejecutará cuando el evento se dispare en el botón.

+ +

You could also set the handler property to be equal to a named function name (like we saw in Build your own function). The following would work just the same:

+ +
var btn = document.querySelector('button');
+
+function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.onclick = bgChange;
+ +

There are many different event handler properties available. Let's do an experiment.

+ +

First of all, make a local copy of random-color-eventhandlerproperty.html, and open it in your browser. It's just a copy of the simple random color example we've been playing with already in this article. Now try changing btn.onclick to the following different values in turn, and observing the results in the example:

+ + + +

Some events are very general and available nearly anywhere (for example an onclick handler can be registered on nearly any element), whereas some are more specific and only useful in certain situations (for example it makes sense to use onplay only on specific elements, such as {{htmlelement("video")}}).

+ +

Inline event handlers — don't use these

+ +

You might also see a pattern like this in your code:

+ +
<button onclick="bgChange()">Press me</button>
+
+ +
function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +
+

Note: You can find the full source code for this example on GitHub (also see it running live).

+
+ +

The earliest method of registering event handlers found on the Web involved event handler HTML attributes (aka inline event handlers) like the one shown above — the attribute value is literally the JavaScript code you want to run when the event occurs. The above example invokes a function defined inside a {{htmlelement("script")}} element on the same page, but you could also insert JavaScript directly inside the attribute, for example:

+ +
<button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button>
+ +

You'll find HTML attribute equivalents for many of the event handler properties; however, you shouldn't use these — they are considered bad practice. It might seem easy to use an event handler attribute if you are just doing something really quick, but they very quickly become unmanageable and inefficient.

+ +

For a start, it is not a good idea to mix up your HTML and your JavaScript, as it becomes hard to parse — keeping your JavaScript all in one place is better; if it is in a separate file you can apply it to multiple HTML documents.

+ +

Even in a single file, inline event handlers are not a good idea. One button is OK, but what if you had 100 buttons? You'd have to add 100 attributes to the file; it would very quickly turn into a maintenance nightmare. With JavaScript, you could easily add an event handler function to all the buttons on the page no matter how many there were, using something like this:

+ +
var buttons = document.querySelectorAll('button');
+
+for (var i = 0; i < buttons.length; i++) {
+  buttons[i].onclick = bgChange;
+}
+ +

Note that another option here would be to use the forEach() built-in method available on all Array objects:

+ +
buttons.forEach(function(button) {
+  button.onclick = bgChange;
+});
+ +
+

Note: Separating your programming logic from your content also makes your site more friendly to search engines.

+
+ +

addEventListener() and removeEventListener()

+ +

The newest type of event mechanism is defined in the Document Object Model (DOM) Level 2 Events Specification, which provides browsers with a new function — addEventListener(). This functions in a similar way to the event handler properties, but the syntax is obviously different. We could rewrite our random color example to look like this:

+ +
var btn = document.querySelector('button');
+
+function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

Note: You can find the full source code for this example on GitHub (also see it running live).

+
+ +

Inside the addEventListener() function, we specify two parameters — the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note that it is perfectly appropriate to put all the code inside the addEventListener() function, in an anonymous function, like this:

+ +
btn.addEventListener('click', function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+});
+ +

This mechanism has some advantages over the older mechanisms discussed earlier. For a start, there is a counterpart function, removeEventListener(), which removes a previously added listener. For example, this would remove the listener set in the first code block in this section:

+ +
btn.removeEventListener('click', bgChange);
+ +

This isn't significant for simple, small programs, but for larger, more complex programs it can improve efficiency to clean up old unused event handlers. Plus, for example, this allows you to have the same button performing different actions in different circumstances — all you've got to do is add/remove event handlers as appropriate.

+ +

Second, you can also register multiple handlers for the same listener. The following two handlers would not be applied:

+ +
myElement.onclick = functionA;
+myElement.onclick = functionB;
+ +

As the second line would overwrite the value of onclick set by the first. This would work, however:

+ +
myElement.addEventListener('click', functionA);
+myElement.addEventListener('click', functionB);
+ +

Both functions would now run when the element is clicked.

+ +

In addition, there are a number of other powerful features and options available with this event mechanism. These are a little out of scope for this article, but if you want to read up on them, have a look at the addEventListener() and removeEventListener() reference pages.

+ +

What mechanism should I use?

+ +

Of the three mechanisms, you definitely shouldn't use the HTML event handler attributes — these are outdated, and bad practice, as mentioned above.

+ +

The other two are relatively interchangeable, at least for simple uses:

+ + + +

The main advantages of the third mechanism are that you can remove event handler code if needed, using removeEventListener(), and you can add multiple listeners of the same type to elements if required. For example, you can call addEventListener('click', function() { ... }) on an element multiple times, with different functions specified in the second argument. This is impossible with event handler properties because any subsequent attempts to set a property will overwrite earlier ones, e.g.:

+ +
element.onclick = function1;
+element.onclick = function2;
+etc.
+ +
+

Note: If you are called upon to support browsers older than Internet Explorer 8 in your work, you may run into difficulties, as such ancient browsers use different event models from newer browsers. But never fear, most JavaScript libraries (for example jQuery) have built-in functions that abstract away cross-browser differences. Don't worry about this too much at this stage in your learning journey.

+
+ +

Other event concepts

+ +

In this section, we will briefly cover some advanced concepts that are relevant to events. It is not important to understand these fully at this point, but it might serve to explain some code patterns you'll likely come across from time to time.

+ +

Event objects

+ +

Sometimes inside an event handler function, you might see a parameter specified with a name such as event, evt, or simply e. This is called the event object, and it is automatically passed to event handlers to provide extra features and information. For example, let's rewrite our random color example again slightly:

+ +
function bgChange(e) {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  e.target.style.backgroundColor = rndCol;
+  console.log(e);
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

Note: You can find the full source code for this example on GitHub (also see it running live).

+
+ +

Here you can see that we are including an event object, e, in the function, and in the function setting a background color style on e.target — which is the button itself. The target property of the event object is always a reference to the element that the event has just occurred upon. So in this example, we are setting a random background color on the button, not the page.

+ +
+

Note: You can use any name you like for the event object — you just need to choose a name that you can then use to reference it inside the event handler function. e/evt/event are most commonly used by developers because they are short and easy to remember. It's always good to stick to a standard.

+
+ +

e.target is incredibly useful when you want to set the same event handler on multiple elements and do something to all of them when an event occurs on them. You might, for example, have a set of 16 tiles that disappear when they are clicked on. It is useful to always be able to just set the thing to disappear as e.target, rather than having to select it in some more difficult way. In the following example (see useful-eventtarget.html for the full source code; also see it running live here), we create 16 {{htmlelement("div")}} elements using JavaScript. We then select all of them using {{domxref("document.querySelectorAll()")}}, then loop through each one, adding an onclick handler to each that makes it so that a random color is applied to each one when clicked:

+ +
var divs = document.querySelectorAll('div');
+
+for (var i = 0; i < divs.length; i++) {
+  divs[i].onclick = function(e) {
+    e.target.style.backgroundColor = bgChange();
+  }
+}
+ +

The output is as follows (try clicking around on it — have fun):

+ + + +

{{ EmbedLiveSample('Hidden_example', '100%', 400, "", "", "hide-codepen-jsfiddle") }}

+ +

Most event handlers you'll encounter just have a standard set of properties and functions (methods) available on the event object (see the {{domxref("Event")}} object reference for a full list). Some more advanced handlers, however, add specialist properties containing extra data that they need to function. The Media Recorder API, for example, has a dataavailable event, which fires when some audio or video has been recorded and is available for doing something with (for example saving it, or playing it back). The corresponding ondataavailable handler's event object has a data property available containing the recorded audio or video data to allow you to access it and do something with it.

+ +

Preventing default behavior

+ +

Sometimes, you'll come across a situation where you want to stop an event doing what it does by default. The most common example is that of a web form, for example, a custom registration form. When you fill in the details and press the submit button, the natural behaviour is for the data to be submitted to a specified page on the server for processing, and the browser to be redirected to a "success message" page of some kind (or the same page, if another is not specified.)

+ +

The trouble comes when the user has not submitted the data correctly — as a developer, you'll want to stop the submission to the server and give them an error message telling them what's wrong and what needs to be done to put things right. Some browsers support automatic form data validation features, but since many don't, you are advised to not rely on those and implement your own validation checks. Let's look at a simple example.

+ +

First, a simple HTML form that requires you to enter your first and last name:

+ +
<form>
+  <div>
+    <label for="fname">First name: </label>
+    <input id="fname" type="text">
+  </div>
+  <div>
+    <label for="lname">Last name: </label>
+    <input id="lname" type="text">
+  </div>
+  <div>
+     <input id="submit" type="submit">
+  </div>
+</form>
+<p></p>
+ + + +

Now some JavaScript — here we implement a very simple check inside an onsubmit event handler (the submit event is fired on a form when it is submitted) that tests whether the text fields are empty. If they are, we call the preventDefault() function on the event object — which stops the form submission — and then display an error message in the paragraph below our form to tell the user what's wrong:

+ +
var form = document.querySelector('form');
+var fname = document.getElementById('fname');
+var lname = document.getElementById('lname');
+var submit = document.getElementById('submit');
+var para = document.querySelector('p');
+
+form.onsubmit = function(e) {
+  if (fname.value === '' || lname.value === '') {
+    e.preventDefault();
+    para.textContent = 'You need to fill in both names!';
+  }
+}
+ +

Obviously, this is pretty weak form validation — it wouldn't stop the user validating the form with spaces or numbers entered into the fields, for example — but it is ok for example purposes. The output is as follows:

+ +

{{ EmbedLiveSample('Preventing_default_behavior', '100%', 140, "", "", "hide-codepen-jsfiddle") }}

+ +
+

Note: for the full source code, see preventdefault-validation.html (also see it running live here.)

+
+ +

Event bubbling and capture

+ +

The final subject to cover here is something that you'll not come across often, but it can be a real pain if you don't understand it. Event bubbling and capture are two mechanisms that describe what happens when two handlers of the same event type are activated on one element. Let's look at an example to make this easier — open up the show-video-box.html example in a new tab (and the source code in another tab.) It is also available live below:

+ + + +

{{ EmbedLiveSample('Hidden_video_example', '100%', 500, "", "", "hide-codepen-jsfiddle") }}

+ +

This is a pretty simple example that shows and hides a {{htmlelement("div")}} with a {{htmlelement("video")}} element inside it:

+ +
<button>Display video</button>
+
+<div class="hidden">
+  <video>
+    <source src="rabbit320.mp4" type="video/mp4">
+    <source src="rabbit320.webm" type="video/webm">
+    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+  </video>
+</div>
+ +

When the {{htmlelement("button")}} is clicked, the video is displayed, by changing the class attribute on the <div> from hidden to showing (the example's CSS contains these two classes, which position the box off the screen and on the screen, respectively):

+ +
btn.onclick = function() {
+  videoBox.setAttribute('class', 'showing');
+}
+ +

We then add a couple more onclick event handlers — the first one to the <div> and the second one to the <video>. The idea is that when the area of the <div> outside the video is clicked, the box should be hidden again; when the video itself is clicked, the video should start to play.

+ +
videoBox.onclick = function() {
+  videoBox.setAttribute('class', 'hidden');
+};
+
+video.onclick = function() {
+  video.play();
+};
+ +

But there's a problem — currently, when you click the video it starts to play, but it causes the <div> to also be hidden at the same time. This is because the video is inside the <div> — it is part of it — so clicking on the video actually runs both the above event handlers.

+ +

Bubbling and capturing explained

+ +

When an event is fired on an element that has parent elements (e.g. the {{htmlelement("video")}} in our case), modern browsers run two different phases — the capturing phase and the bubbling phase.

+ +

In the capturing phase:

+ + + +

In the bubbling phase, the exact opposite occurs:

+ + + +

+ +

(Click on image for bigger diagram)

+ +

In modern browsers, by default, all event handlers are registered in the bubbling phase. So in our current example, when you click the video, the click event bubbles from the <video> element outwards to the <html> element. Along the way:

+ + + +

Fixing the problem with stopPropagation()

+ +

This is annoying behavior, but there is a way to fix it! The standard event object has a function available on it called stopPropagation(), which when invoked on a handler's event object makes it so that handler is run, but the event doesn't bubble any further up the chain, so no more handlers will be run.

+ +

We can, therefore, fix our current problem by changing the second handler function in the previous code block to this:

+ +
video.onclick = function(e) {
+  e.stopPropagation();
+  video.play();
+};
+ +

You can try making a local copy of the show-video-box.html source code and having a go at fixing it yourself, or looking at the fixed result in show-video-box-fixed.html (also see the source code here).

+ +
+

Note: Why bother with both capturing and bubbling? Well, in the bad old days when browsers were much less cross-compatible than they are now, Netscape only used event capturing, and Internet Explorer used only event bubbling. When the W3C decided to try to standardize the behavior and reach a consensus, they ended up with this system that included both, which is the one modern browsers implemented.

+
+ +
+

Note: As mentioned above, by default all event handlers are registered in the bubbling phase, and this makes more sense most of the time. If you really want to register an event in the capturing phase instead, you can do so by registering your handler using addEventListener(), and setting the optional third property to true.

+
+ +

Event delegation

+ +

Bubbling also allows us to take advantage of event delegation — this concept relies on the fact that if you want some code to run when you click on any one of a large number of child elements, you can set the event listener on their parent and have events that happen on them bubble up to their parent rather than having to set the event listener on every child individually. Remember earlier that we said bubbling involves checking the element the event is fired on for an event handler first, then moving up to the element's parent, etc.?

+ +

A good example is a series of list items — if you want each one of them to pop up a message when clicked, you can set the click event listener on the parent <ul>, and events will bubble from the list items to the <ul>.

+ +

This concept is explained further on David Walsh's blog, with multiple examples — see How JavaScript Event Delegation Works.

+ +

Conclusion

+ +

You should now know all you need to know about web events at this early stage. As mentioned above, events are not really part of the core JavaScript — they are defined in browser Web APIs.

+ +

Also, it is important to understand that the different contexts in which JavaScript is used tend to have different event models — from Web APIs to other areas such as browser WebExtensions and Node.js (server-side JavaScript). We are not expecting you to understand all these areas now, but it certainly helps to understand the basics of events as you forge ahead with learning web development.

+ +

If there is anything you didn't understand, feel free to read through the article again, or contact us to ask for help.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}

+ +

In this module

+ + diff --git a/files/es/learn/javascript/building_blocks/functions/index.html b/files/es/learn/javascript/building_blocks/functions/index.html new file mode 100644 index 0000000000..d05ae34969 --- /dev/null +++ b/files/es/learn/javascript/building_blocks/functions/index.html @@ -0,0 +1,400 @@ +--- +title: Funciones — bloques de código reutilizables +slug: Learn/JavaScript/Building_blocks/Functions +tags: + - API + - Funciones + - JavaScript + - Métodos + - Navegador +translation_of: Learn/JavaScript/Building_blocks/Functions +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}
+ +

Otro concepto esencial en la codificación son las funciones, que te permiten almacenar un fragmento de código que realiza una única tarea dentro de un bloque definido, y luego llamar a ese código siempre que lo necesites utilizando un único comando breve -- en lugar de tener que escribir el mismo codigo varias veces. En este artículo exploraremos conceptos fundamentales detrás de funciones tales como sintaxis básica, cómo invocarlas y definirlas, alcance(scope) y parámetros.

+ + + + + + + + + + + + +
Prerequisites:Conocimientos basicos de informatica, conocimiento basico de   HTML y CSS, JavaScript first steps.
Objective:Entender los conceptos fundamentales detras de las funciones JavaScript.
+ +

¿Dónde encuentro las funciones? 

+ +

En JavaScript vas a encontrar funciones por todos lados. De hecho, nosotros hemos usados funciones todo el tiempo a lo largo del curso; solo que no hemos hablado mucho sobre ellas. Ahora es el momento, igual, para comenzar a hablar explicitamente sobre las funciones y explorar su sintaxis.

+ +

Básicamente cada vez que haces uso de código JavaScript que contiene parentesis como () y no estás usando estructuras de lenguaje como for loop, while, do, do while, estás usando una función! 

+ +

Funciones incluídas en los navegadores

+ +

A lo largo de este curso hemos usado muchas funciones incluídas del navegador. Por ejemplo, cuando manipulamos una cadena de texto o string:

+ +
let miTexto = 'Soy una cadena de texto!';
+let nuevaCadena = miTexto.replace('cadena', 'ensalada');
+console.log(nuevaCadena);
+// la función de cadena de texto replace() toma una cadena,
+// reemplaza una palabra por otra, y devuelve
+// una nueva cadena con el reemplazo hecho.
+ +

O cada vez que manipulamos un array:

+ +
let miArray = ['Yo', 'amo', 'el', 'chocolate', 'y', 'las', 'ranas'];
+let armarCadena = miArray.join(' ');
+console.log(armarCadena);
+// La función join() toma un array,
+// une todos sus elementos en una cadena o string
+// y devuelve esta nueva cadena.
+ +

O cada vez que generamos un número al azar:

+ +
var miNumero = Math.random();
+console.log(miNumero);
+// La función Math.random() genera un número aleatorio
+// entre 0 and 1 y devuelve ese número.
+
+ +

...estamos usando una función!

+ +
+

Nota: Sientase libre de ingresar esas líneas de código en la consola JavaScript de su navegador, para familiarizarse con sus funcionalidades. 

+
+ +

El lenguaje JavaScript contiene muchas funciones integradas que te permiten realizar cosas muy utilies sin escribir el código tu mismo. De hecho, parte del código que llamas (una palabra elegante para decir correr o ejecutar) cuando invocas una función integrada puede no estar escrita en JavaScript —muchas de estas funciones están llamando partes del código del navegador de fondo, que está escrito principalmente en lenguajes de sistema de bajo nivel como C ++, no en lenguajes web como JavaScript.

+ +

Bear in mind that some built-in browser functions are not part of the core JavaScript language — some are defined as part of browser APIs, which build on top of the default language to provide even more functionality (refer to this early section of our course for more descriptions). We'll look at using browser APIs in more detail in a later module.

+ +

Functions versus methods

+ +

One thing we need to clear up before we move on — technically speaking, built in browser functions are not functions — they are methods. This sounds a bit scary and confusing, but don't worry — the words function and method are largely interchangeable, at least for our purposes, at this stage in your learning.

+ +

The distinction is that methods are functions defined inside objects. Built-in browser functions (methods) and variables (which are called properties) are stored inside structured objects, to make the code more efficient and easier to handle.

+ +

You don't need to learn about the inner workings of structured JavaScript objects yet — you can wait until our later module that will teach you all about the inner workings of objects, and how to create your own. For now, we just wanted to clear up any possible confusion of method versus function — you are likely to meet both terms as you look at the available related resources across the Web.

+ +

Custom functions

+ +

You've also seen a lot of custom functions in the course so far — functions defined in your code, not inside the browser. Anytime you saw a custom name with parentheses straight after it, you were using a custom function. In our random-canvas-circles.html example (see also the full source code) from our loops article, we included a custom draw() function that looked like this:

+ +
function draw() {
+  ctx.clearRect(0,0,WIDTH,HEIGHT);
+  for (var i = 0; i < 100; i++) {
+    ctx.beginPath();
+    ctx.fillStyle = 'rgba(255,0,0,0.5)';
+    ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+    ctx.fill();
+  }
+}
+ +

This function draws 100 random circles inside an {{htmlelement("canvas")}} element. Every time we want to do that, we can just invoke the function with this

+ +
draw();
+ +

rather than having to write all that code out again every time we want to repeat it. And functions can contain whatever code you like — you can even call other functions from inside functions. The above function for example calls the random() function three times, which is defined by the following code:

+ +
function random(number) {
+  return Math.floor(Math.random()*number);
+}
+ +

We needed this function because the browser's built-in Math.random() function only generates a random decimal number between 0 and 1. We wanted a random whole number between 0 and a specified number.

+ +

Invoking functions

+ +

You are probably clear on this by now, but just in case ... to actually use a function after it has been defined, you've got to run — or invoke — it. This is done by including the name of the function in the code somewhere, followed by parentheses.

+ +
function myFunction() {
+  alert('hello');
+}
+
+myFunction()
+// calls the function once
+ +

Anonymous functions

+ +

You may see functions defined and invoked in slightly different ways. So far we have just created a function like so:

+ +
function myFunction() {
+  alert('hello');
+}
+ +

But you can also create a function that doesn't have a name:

+ +
function() {
+  alert('hello');
+}
+ +

This is called an anonymous function — it has no name! It also won't do anything on its own. You generally use an anonymous function along with an event handler, for example the following would run the code inside the function whenever the associated button is clicked:

+ +
var myButton = document.querySelector('button');
+
+myButton.onclick = function() {
+  alert('hello');
+}
+ +

The above example would require there to be a {{htmlelement("button")}} element available on the page to select and click. You've already seen this structure a few times throughout the course, and you'll learn more about and see it in use in the next article.

+ +

You can also assign an anonymous function to be the value of a variable, for example:

+ +
var myGreeting = function() {
+  alert('hello');
+}
+ +

This function could now be invoked using:

+ +
myGreeting();
+ +

This effectively gives the function a name; you can also assign the function to be the value of multiple variables, for example:

+ +
var anotherGreeting = function() {
+  alert('hello');
+}
+ +

This function could now be invoked using either of

+ +
myGreeting();
+anotherGreeting();
+ +

But this would just be confusing, so don't do it! When creating functions, it is better to just stick to this form:

+ +
function myGreeting() {
+  alert('hello');
+}
+ +

You will mainly use anonymous functions to just run a load of code in response to an event firing — like a button being clicked — using an event handler. Again, this looks something like this:

+ +
myButton.onclick = function() {
+  alert('hello');
+  // I can put as much code
+  // inside here as I want
+}
+ +

Function parameters

+ +

Some functions require parameters to be specified when you are invoking them — these are values that need to be included inside the function parentheses, which it needs to do its job properly.

+ +
+

Note: Parameters are sometimes called arguments, properties, or even attributes.

+
+ +

As an example, the browser's built-in Math.random() function doesn't require any parameters. When called, it always returns a random number between 0 and 1:

+ +
var myNumber = Math.random();
+ +

The browser's built-in string replace() function however needs two parameters — the substring to find in the main string, and the substring to replace that string with:

+ +
var myText = 'I am a string';
+var newString = myText.replace('string', 'sausage');
+ +
+

Note: When you need to specify multiple parameters, they are separated by commas.

+
+ +

It should also be noted that sometimes parameters are optional — you don't have to specify them. If you don't, the function will generally adopt some kind of default behavior. As an example, the array join() function's parameter is optional:

+ +
var myArray = ['I', 'love', 'chocolate', 'frogs'];
+var madeAString = myArray.join(' ');
+// returns 'I love chocolate frogs'
+var madeAString = myArray.join();
+// returns 'I,love,chocolate,frogs'
+ +

If no parameter is included to specify a joining/delimiting character, a comma is used by default.

+ +

Function scope and conflicts

+ +

Let's talk a bit about {{glossary("scope")}} — a very important concept when dealing with functions. When you create a function, the variables and other things defined inside the function are inside their own separate scope, meaning that they are locked away in their own separate compartments, unreachable from inside other functions or from code outside the functions.

+ +

The top level outside all your functions is called the global scope. Values defined in the global scope are accessible from everywhere in the code.

+ +

JavaScript is set up like this for various reasons — but mainly because of security and organization. Sometimes you don't want variables to be accessible from everywhere in the code — external scripts that you call in from elsewhere could start to mess with your code and cause problems because they happen to be using the same variable names as other parts of the code, causing conflicts. This might be done maliciously, or just by accident.

+ +

For example, say you have an HTML file that is calling in two external JavaScript files, and both of them have a variable and a function defined that use the same name:

+ +
<!-- Excerpt from my HTML -->
+<script src="first.js"></script>
+<script src="second.js"></script>
+<script>
+  greeting();
+</script>
+ +
// first.js
+var name = 'Chris';
+function greeting() {
+  alert('Hello ' + name + ': welcome to our company.');
+}
+ +
// second.js
+var name = 'Zaptec';
+function greeting() {
+  alert('Our company is called ' + name + '.');
+}
+ +

Both functions you want to call are called greeting(), but you can only ever access the second.js file's greeting() function — it is applied to the HTML later on in the source code, so its variable and function overwrite the ones in first.js.

+ +
+

Note: You can see this example running live on GitHub (see also the source code).

+
+ +

Keeping parts of your code locked away in functions avoids such problems, and is considered best practice.

+ +

It is a bit like a zoo. The lions, zebras, tigers, and penguins are kept in their own enclosures, and only have access to the things inside their enclosures — in the same manner as the function scopes. If they were able to get into other enclosures, problems would occur. At best, different animals would feel really uncomfortable inside unfamiliar habitats — a lion or tiger would feel terrible inside the penguins' watery, icy domain. At worst, the lions and tigers might try to eat the penguins!

+ +

+ +

The zoo keeper is like the global scope — he or she has the keys to access every enclosure, to restock food, tend to sick animals, etc.

+ +

Active learning: Playing with scope

+ +

Let's look at a real example to demonstrate scoping.

+ +
    +
  1. First, make a local copy of our function-scope.html example. This contains two functions called a() and b(), and three variables — x, y, and z — two of which are defined inside the functions, and one in the global scope. It also contains a third function called output(), which takes a single parameter and outputs it in a paragraph on the page.
  2. +
  3. Open the example up in a browser and in your text editor.
  4. +
  5. Open the JavaScript console in your browser developer tools. In the JavaScript console, enter the following command: +
    output(x);
    + You should see the value of variable x output to the screen.
  6. +
  7. Now try entering the following in your console +
    output(y);
    +output(z);
    + Both of these should return an error along the lines of "ReferenceError: y is not defined". Why is that? Because of function scope — y and z are locked inside the a() and b() functions, so output() can't access them when called from the global scope.
  8. +
  9. However, what about when it's called from inside another function? Try editing a() and b() so they look like this: +
    function a() {
    +  var y = 2;
    +  output(y);
    +}
    +
    +function b() {
    +  var z = 3;
    +  output(z);
    +}
    + Save the code and reload it in your browser, then try calling the a() and b() functions from the JavaScript console: + +
    a();
    +b();
    + You should see the y and z values output in the page. This works fine, as the output() function is being called inside the other functions — in the same scope as the variables it is printing are defined in, in each case. output() itself is available from anywhere, as it is defined in the global scope.
  10. +
  11. Now try updating your code like this: +
    function a() {
    +  var y = 2;
    +  output(x);
    +}
    +
    +function b() {
    +  var z = 3;
    +  output(x);
    +}
    + Save and reload again, and try this again in your JavaScript console: + +
    a();
    +b();
    + Both the a() and b() call should output the value of x — 1. These work fine because even though the output() calls are not in the same scope as x is defined in, x is a global variable so is available inside all code, everywhere.
  12. +
  13. Finally, try updating your code like this: +
    function a() {
    +  var y = 2;
    +  output(z);
    +}
    +
    +function b() {
    +  var z = 3;
    +  output(y);
    +}
    + Save and reload again, and try this again in your JavaScript console: + +
    a();
    +b();
    + This time the a() and b() calls will both return that annoying "ReferenceError: z is not defined" error — this is because the output() calls and the variables they are trying to print are not defined inside the same function scopes — the variables are effectively invisible to those function calls.
  14. +
+ +
+

Note: The same scoping rules do not apply to loop (e.g. for() { ... }) and conditional blocks (e.g. if() { ... }) — they look very similar, but they are not the same thing! Take care not to get these confused.

+
+ +
+

Note: The ReferenceError: "x" is not defined error is one of the most common you'll encounter. If you get this error and you are sure that you have defined the variable in question, check what scope it is in.

+
+ + + +

Functions inside functions

+ +

Keep in mind that you can call a function from anywhere, even inside another function.  This is often used as a way to keep code tidy — if you have a big complex function, it is easier to understand if you break it down into several sub-functions:

+ +
function myBigFunction() {
+  var myValue;
+
+  subFunction1();
+  subFunction2();
+  subFunction3();
+}
+
+function subFunction1() {
+  console.log(myValue);
+}
+
+function subFunction2() {
+  console.log(myValue);
+}
+
+function subFunction3() {
+  console.log(myValue);
+}
+
+ +

Just make sure that the values being used inside the function are properly in scope. The example above would throw an error ReferenceError: myValue is not defined, because although the myValue variable is defined in the same scope as the function calls, it is not defined inside the function definitions — the actual code that is run when the functions are called. To make this work, you'd have to pass the value into the function as a parameter, like this:

+ +
function myBigFunction() {
+  var myValue = 1;
+
+  subFunction1(myValue);
+  subFunction2(myValue);
+  subFunction3(myValue);
+}
+
+function subFunction1(value) {
+  console.log(value);
+}
+
+function subFunction2(value) {
+  console.log(value);
+}
+
+function subFunction3(value) {
+  console.log(value);
+}
+ +

Conclusion

+ +

This article has explored the fundamental concepts behind functions, paving the way for the next one in which we get practical and take you through the steps to building up your own custom function.

+ +

See also

+ + + + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}

+ +

In this module

+ + +<gdiv></gdiv> diff --git a/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html b/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html new file mode 100644 index 0000000000..205f1a11aa --- /dev/null +++ b/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html @@ -0,0 +1,144 @@ +--- +title: Galería de imágenes +slug: Learn/JavaScript/Building_blocks/Galeria_de_imagenes +translation_of: Learn/JavaScript/Building_blocks/Image_gallery +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}
+ +

Ahora que hemos analizado los bloques de construcción fundamentales de JavaScript, pongamos a prueba tu conocimiento de bucles, funciones, condicionales y eventos, creando un elemento que comumente vemos en muchos sitios web, una Galería de imágenes "motorizada" por JavaScript .

+ + + + + + + + + + + + +
Prerequisitos:Antes de intentar esta evaluación deberías de haber trabajado con todos los artículos en éste módulo.
Objetivo:Evaluar la comprensión de los bucles, funciones, condicionales y eventos de JavaScript..
+ +

Punto de partida

+ +

Para realizar esta evaluación, debería descárgarse archivoZip para el ejemplo, descomprímalo en algún lugar de su computadora y haga el ejercicio localmente para empezar.

+ +

Opcionalmente, puedes usar un sitio como JSBin o Glitch para realizar tu evaluación. Puede pegar el HTML, CSS y JavaScript dentro de uno de estos editores online. Si el editor en línea que está utilizando no tiene paneles JavaScript / CSS separados, siéntase libre de ponerlos en línea <script> / <style> elementos dentro de la página HTML.

+ +
+

Nota: Si se atascascas con algo, entonces pregúntenos para ayudarlo — vea la sección de {{anch("evaluación o ayuda adicional")}} al final de esta página.

+
+ +

Resumen del proyecto

+ +

Ha sido provisto con algún contenido de HTML, CSS e imágenes, también algunas líneas de código en JavaScript; necesitas escribir las líneas de código en JavaScript necesatio para transformarse en un programa funcional. El  HTML body luce así:

+ +
<h1>Image gallery example</h1>
+
+<div class="full-img">
+  <img class="displayed-img" src="images/pic1.jpg">
+  <div class="overlay"></div>
+  <button class="dark">Darken</button>
+</div>
+
+<div class="thumb-bar">
+
+</div>
+ +

El ejemplo se ve así:

+ +

+ + + +

Las partes más interesantes del archivo example's CSS :

+ + + +

Your JavaScript needs to:

+ + + +

To give you more of an idea, have a look at the finished example (no peeking at the source code!)

+ +

Steps to complete

+ +

The following sections describe what you need to do.

+ +

Looping through the images

+ +

We've already provided you with lines that store a reference to the thumb-bar <div> inside a constant called thumbBar, create a new <img> element, set its src attribute to a placeholder value xxx, and append this new <img> element inside thumbBar.

+ +

You need to:

+ +
    +
  1. Put the section of code below the "Looping through images" comment inside a loop that loops through all 5 images — you just need to loop through five numbers, one representing each image.
  2. +
  3. In each loop iteration, replace the xxx placeholder value with a string that will equal the path to the image in each case. We are setting the value of the src attribute to this value in each case. Bear in mind that in each case, the image is inside the images directory and its name is pic1.jpg, pic2.jpg, etc.
  4. +
+ +

Adding an onclick handler to each thumbnail image

+ +

In each loop iteration, you need to add an onclick handler to the current newImage — this handler should find the value of the src attribute of the current image. Set the src attribute value of the displayed-img <img> to the src value passed in as a parameter.

+ +

Writing a handler that runs the darken/lighten button

+ +

That just leaves our darken/lighten <button> — we've already provided a line that stores a reference to the <button> in a constant called btn. You need to add an onclick handler that:

+ +
    +
  1. Checks the current class name set on the <button> — you can again achieve this by using getAttribute().
  2. +
  3. If the class name is "dark", changes the <button> class to "light" (using setAttribute()), its text content to "Lighten", and the {{cssxref("background-color")}} of the overlay <div> to "rgba(0,0,0,0.5)".
  4. +
  5. If the class name not "dark", changes the <button> class to "dark", its text content back to "Darken", and the {{cssxref("background-color")}} of the overlay <div> to "rgba(0,0,0,0)".
  6. +
+ +

The following lines provide a basis for achieving the changes stipulated in points 2 and 3 above.

+ +
btn.setAttribute('class', xxx);
+btn.textContent = xxx;
+overlay.style.backgroundColor = xxx;
+ +

Hints and tips

+ + + +

Assessment or further help

+ +

If you would like your work assessed, or are stuck and want to ask for help:

+ +
    +
  1. Put your work into an online shareable editor such as CodePen, jsFiddle, or Glitch.
  2. +
  3. Write a post asking for assessment and/or help at the MDN Discourse forum Learning category. Your post should include: +
      +
    • A descriptive title such as "Assessment wanted for Image gallery".
    • +
    • Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.
    • +
    • A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.
    • +
    • A link to the actual task or assessment page, so we can find the question you want help with.
    • +
    +
  4. +
+ +

{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}

+ +

In this module

+ + diff --git a/files/es/learn/javascript/building_blocks/index.html b/files/es/learn/javascript/building_blocks/index.html new file mode 100644 index 0000000000..de9e7c7c4a --- /dev/null +++ b/files/es/learn/javascript/building_blocks/index.html @@ -0,0 +1,71 @@ +--- +title: Elementos básicos de JavaScript +slug: Learn/JavaScript/Building_blocks +tags: + - CodingScripting + - Condicionales + - Evaluación + - Funciones + - Guía + - JavaScript + - Landing + - NeedsTranslation + - Principiante + - TopicStub + - bucles + - eventos + - introducción + - 'l10n:priority' + - modulo +translation_of: Learn/JavaScript/Building_blocks +--- +
{{LearnSidebar}}
+ +

En este módulo, continuamos nuestra cobertura de todas las características clave de JavaScript, tornando nuestra atención a tipos de código comúnmente encontrados tales como enunciados condicionales, bucles (loops), funciones, y eventos. Ya has visto estas cosas en este curso, pero solo de pasada aquí lo hablaremos mas explícitamente.

+ +

Quieres transformarte en un desarrollador web front-end?

+ +

Hemos reunido un curso que incluye toda la información esencial que necesitas para trabajar hacia tu objetivo.

+ +

Empieza aquí

+ +

Pre-requisitos

+ +

Antes de empezar este módulo, deberías ya tener alguna familiaridad con lo básico de HTML y CSS,  y también deberías haber trabajado todos lo módulos previos, JavaScript primeros pasos.

+ +
+

Nota: Si estas trabajando en una computadora/tablet/otro dispositivo donde no tienes la capacidad de crear tus propios archivos, podrías practicar (la mayoría de) los ejemplos de código en un programa en linea tales como JSBin o Thimble.

+
+ +

Guías

+ +
+
 Tomando decisiones en tu código — condicionales
+
En cualquier lenguaje de programación, el código necesita tomar decisiones y efectuar acciones consiguientemente dependiendo de las diferentes ordenes ingresadas. Por ejemplo, en un juego, si el numero de vidas del jugador es 0, entonces se termina el juego. En una aplicación del clima, si esta siendo vista por la mañana, muestra un gráfico del amanecer; muestra estrellas y una luna si es de noche. En este artículo exploraremos como los condicionales estructuran el trabajo en Javascript.
+
Bucles de código
+
A veces necesitas que una tarea se haga más de una vez. Por ejemplo, revisar toda una lista de nombres. En programación, los bucles ('loops' en inglés) hacen este trabajo muy bien. Aca veremos la estructura de loops en Javascript.
+
Funciones — bloques de código reusables
+
Otro concepto fundamental en código es funciones. Funciones te permite almacenar una pieza de código que ejecuta una sola tarea dentro de un bloque definido, y después llamar ese código cuando lo necesitas usando un comando corto  en lugar de tener que escribir el mismo código varias veces. En este articulo exploraremos conceptos fundamentales detrás de las funciones tales como sintaxis básica, cómo invocar y definir funciones, ámbito o alcance (scope), y parámetros.
+
Crea tu propia función
+
Con la información presentada en el artículo anterior, este artículo, pretende demostrar una parte práctica. Se podrá desarrollar una función propia, y durante el desarrollo se presentarán algunos consejos prácticos y útiles para trabajar con funciones.
+
 Una función devuelve valores
+
Un concepto fundamental que ha de tenerse en cuenta, es que las funciones pueden devolver valores al finalizar su ejecución, aunque algunas funciones también pueden no devolver ningún valor. Es importante entender como son esos valores, qué tipos pueden tener y cómo aprovechar el valor devuelto por la función en el programa.
+
Introducción a eventos
+
Los eventos son acciones u ocurrencias que aparecen durante la ejecución del programa, y que son reportadas por el sistema, de forma que se pueda responder a los eventos de la forma deseada. Por ejemplo, si un usuario hace un click en un botón de una página web, puede que se quiera que ese evento inicie una acción en el que se muestre cierta información en un cuadro de información.  En este último artículo se presentarán y describirán los conceptos necesarios con respecto a los eventos, y como funcionan en un navegador.
+
+ +

Evaluaciones

+ +

La siguiente evaluación probara tu entendimiento de lo básico de Javascript cubierto en las guias anteriores.

+ +
+
Galeria de imagen
+
Ahora que hemos visto los bloques constructores fundamentales de JavaScript, probaremos tus conocimientos en bucles, funciones, condicionales y eventos construyendo un item bastante común en muchos sitios web — una galería de imágenes creada con JavaScript. 
+
+ +

Ver también

+ +
+
Aprender JavaScript
+
Un excelente recurso para aspirantes a desarrolladores web — Aprenda JavaScript en un entorno interactivo, con lecciones cortas y pruebas interactivas, guiadas por una evaluación automatizada. Las primeras 40 lecciones son gratuitas, y el curso completo está disponible por un pequeño pago único.
+
diff --git a/files/es/learn/javascript/building_blocks/return_values/index.html b/files/es/learn/javascript/building_blocks/return_values/index.html new file mode 100644 index 0000000000..2602a7217f --- /dev/null +++ b/files/es/learn/javascript/building_blocks/return_values/index.html @@ -0,0 +1,168 @@ +--- +title: Una función retorna valores +slug: Learn/JavaScript/Building_blocks/Return_values +translation_of: Learn/JavaScript/Building_blocks/Return_values +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}
+ +

Hay un último concepto esencial para que discutamos en este curso, para cerrar nuestra visión de las funciones: — lo valores que se devuelven. Algunas funciones no devuelven un valor significativo después de su finalización, pero otras sí, y es importante comprender cuáles son sus valores, cómo utilizarlos en su código y cómo hacer que sus propias funciones personalizadas devuelvan valores útiles. Cubriremos todos estos a continuación.

+ + + + + + + + + + + + +
Prerequisites: +

Basic computer literacy, a basic understanding of HTML and CSS, JavaScript first steps, Functions — reusable blocks of code.

+
Objective:To understand function return values, and how to make use of them.
+ +

¿Qué son los valores de retorno?

+ +

Los valores de retorno son exactamente como suenan: los valores devueltos por la función cuando se completa. Ya has alcanzado los valores de retorno varias veces, aunque es posible que no hayas pensado en ellos explícitamente. Volvamos a un código familiar:

+ +
var myText = 'I am a string';
+var newString = myText.replace('string', 'sausage');
+console.log(newString);
+// la función de cadena replace () toma una cadena,
+// sustituyendo una subcadena con otra y devoviendo
+// ​​una cadena nueva con la sustitución realizada
+ +

Vimos exactamente este bloque de código en nuestro primer artículo de función. Estamos invocando la función replace () en la cadena myText, y le pasamos dos parámetros: la subcadena a encontrar y la subcadena con la que reemplazarla. Cuando esta función se completa (termina de ejecutarse), devuelve un valor, que es una nueva cadena con el reemplazo realizado. En el código anterior, estamos guardando este valor de retorno como el valor de la variable newString.

+ +

Si observa la página de referencia MDN de la función de reemplazo, verá una sección llamada Valor de retorno. Es muy útil conocer y comprender qué valores devuelven las funciones, por lo que tratamos de incluir esta información siempre que sea posible.

+ +

Algunas funciones no devuelven un valor de retorno como tal (en nuestras páginas de referencia, el valor de retorno aparece como void o undefined en tales casos). Por ejemplo, en la función displayMessage () que creamos en el artículo anterior, no se devuelve ningún valor específico como resultado de la función que se invoca. Simplemente hace que aparezca un cuadro en algún lugar de la pantalla, ¡eso es todo!

+ +

Generalmente, se usa un valor de retorno donde la función es un paso intermedio en un cálculo de algún tipo. Quieres llegar a un resultado final, que involucra algunos valores. Esos valores deben ser calculados por una función, que luego devuelve los resultados para que puedan usarse en la siguiente etapa del cálculo.

+ +

Using return values in your own functions

+ +

To return a value from a custom function, you need to use ... wait for it ... the return keyword. We saw this in action recently in our random-canvas-circles.html example. Our draw() function draws 100 random circles somewhere on an HTML {{htmlelement("canvas")}}:

+ +
function draw() {
+  ctx.clearRect(0,0,WIDTH,HEIGHT);
+  for (var i = 0; i < 100; i++) {
+    ctx.beginPath();
+    ctx.fillStyle = 'rgba(255,0,0,0.5)';
+    ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+    ctx.fill();
+  }
+}
+ +

Inside each loop iteration, three calls are made to the random() function, to generate a random value for the current circle's x coordinate, y coordinate, and radius, respectively. The random() function takes one parameter — a whole number — and it returns a whole random number between 0 and that number. It looks like this:

+ +
function randomNumber(number) {
+  return Math.floor(Math.random()*number);
+}
+ +

This could be written as follows:

+ +
function randomNumber(number) {
+  var result = Math.floor(Math.random()*number);
+  return result;
+}
+ +

But the first version is quicker to write, and more compact.

+ +

We are returning the result of the calculation Math.floor(Math.random()*number) each time the function is called. This return value appears at the point the function was called, and the code continues. So for example, if we ran the following line:

+ +
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ +

and the three random() calls returned the values 500, 200, and 35, respectively, the line would actually be run as if it were this:

+ +
ctx.arc(500, 200, 35, 0, 2 * Math.PI);
+ +

The function calls on the line are run first and their return values substituted for the function calls, before the line itself is then executed.

+ +

Active learning: our own return value function

+ +

Let's have a go at writing our own functions featuring return values.

+ +
    +
  1. First of all, make a local copy of the function-library.html file from GitHub. This is a simple HTML page containing a text {{htmlelement("input")}} field and a paragraph. There's also a {{htmlelement("script")}} element in which we have stored a reference to both HTML elements in two variables. This little page will allow you to enter a number into the text box, and display different numbers related to it in the paragraph below.
  2. +
  3. Let's add some useful functions to this <script> element. Below the existing two lines of JavaScript, add the following function definitions: +
    function squared(num) {
    +  return num * num;
    +}
    +
    +function cubed(num) {
    +  return num * num * num;
    +}
    +
    +function factorial(num) {
    +  var x = num;
    +  while (x > 1) {
    +    num *= x-1;
    +    x--;
    +  }
    +  return num;
    +}
    + The squared() and cubed() functions are fairly obvious — they return the square or cube of the number given as a parameter. The factorial() function returns the factorial of the given number.
  4. +
  5. Next, we're going to include a way to print out information about the number entered into the text input. Enter the following event handler below the existing functions: +
    input.onchange = function() {
    +  var num = input.value;
    +  if (isNaN(num)) {
    +    para.textContent = 'You need to enter a number!';
    +  } else {
    +    para.textContent = num + ' squared is ' + squared(num) + '. ' +
    +                       num + ' cubed is ' + cubed(num) + '. ' +
    +                       num + ' factorial is ' + factorial(num) + '.';
    +  }
    +}
    + +

    Here we are creating an onchange event handler that runs whenever the change event fires on the text input — that is, when a new value is entered into the text input, and submitted (enter a value then press tab for example). When this anonymous function runs, the existing value entered into the input is stored in the num variable.

    + +

    Next, we do a conditional test — if the entered value is not a number, we print an error message into the paragraph. The test looks at whether the expression isNaN(num) returns true. We use the isNaN() function to test whether the num value is not a number — if so, it returns true, and if not, false.

    + +

    If the test returns false, the num value is a number, so we print out a sentence inside the paragraph element stating what the square, cube, and factorial of the number are. The sentence calls the squared(), cubed(), and factorial() functions to get the required values.

    +
  6. +
  7. Save your code, load it in a browser, and try it out.
  8. +
+ +
+

Note: If you have trouble getting the example to work, feel free to check your code against the finished version on GitHub (see it running live also), or ask us for help.

+
+ +

At this point, we'd like you to have a go at writing out a couple of functions of your own and adding them to the library. How about the square or cube root of the number, or the circumference of a circle with a radius of length num?

+ +

This exercise has brought up a couple of important points besides being a study on how to use the return statement. In addition, we have:

+ + + +

Conclusion

+ +

So there we have it — functions are fun, very useful and, although there's a lot to talk about in regards to their syntax and functionality, fairly understandable given the right articles to study.

+ +

If there is anything you didn't understand, feel free to read through the article again, or contact us to ask for help.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}

+ +

In this module

+ + diff --git a/files/es/learn/javascript/client-side_web_apis/client-side_storage/index.html b/files/es/learn/javascript/client-side_web_apis/client-side_storage/index.html new file mode 100644 index 0000000000..0c03392e7d --- /dev/null +++ b/files/es/learn/javascript/client-side_web_apis/client-side_storage/index.html @@ -0,0 +1,788 @@ +--- +title: Almacenamiento del lado cliente +slug: Learn/JavaScript/Client-side_web_APIs/Client-side_storage +tags: + - API + - Almacenaje + - Article + - CodingScripting + - Guía + - IndexedDB + - JavaScript + - Principiante + - aprende +translation_of: Learn/JavaScript/Client-side_web_APIs/Client-side_storage +--- +

{{LearnSidebar}}

+ +
{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}
+ +

Los navegadores web modernos admiten varias formas para que los sitios web almacenen datos en la computadora del usuario, con el permiso del usuario, y luego los recuperen cuando sea necesario. Esto te permite conservar los datos para el almacenamiento a largo plazo, guardar sitios o documentos para su uso sin conexión, conservar la configuración específica del usuario para tu sitio y más. Este artículo explica los conceptos básicos de cómo funcionan.

+ + + + + + + + + + + + +
Prerrequisitos:Conceptos básicos de JavaScript (consulta {{web.link("/es/docs/Learn/JavaScript/First_steps", "primeros pasos")}}, {{web.link("/es/docs/Learn/JavaScript/Building_blocks", "bloques de construcción")}}, {{web.link("/es/docs/Learn/JavaScript/Objects", "objetos JavaScript")}}), los {{web.link("/es/docs/Learn/JavaScript/Client-side_web_APIs/Introducción", "conceptos básicos de las APIs de lado del cliente")}}
Objetivo:Aprender a utilizar las APIs de almacenamiento de lado del cliente para almacenar datos de aplicaciones.
+ +

¿Almacenamiento de lado del cliente?

+ +

En otra parte del área de aprendizaje de MDN, hablamos sobre la diferencia entre {{web.link("/es/docs/Learn/Server-side/First_steps/Client-Server_overview#Sitios_estaticos", "sitios estáticos")}} y {{web.link("/es/docs/Learn/Server-side/First_steps/Client-Server_overview#Sitios_dinamicos", "sitios dinámicos")}}. La mayoría de los principales sitios web modernos son dinámicos: almacenan datos en el servidor utilizando algún tipo de base de datos (almacenamiento de lado del servidor) y luego ejecutan {{web.link("/es/docs/Learn/Server-side", "de lado del servidor")}} para recuperar los datos necesarios, insertarlos en plantillas de páginas estáticas y entregar el HTML resultante al cliente para que lo muestre el navegador del usuario.

+ +

El almacenamiento de lado del cliente funciona con principios similares, pero tiene diferentes usos. Consiste en una API de JavaScript que te permiten almacenar datos en el cliente (es decir, en la máquina del usuario) y luego recuperarlos cuando sea necesario. Esto tiene muchos usos distintos, como:

+ + + +

A menudo, el almacenamiento de lado del cliente y de lado del servidor se utilizan juntos. Por ejemplo, puedes descargar un lote de archivos de música (quizás utilizados por un juego web o una aplicación de reproducción de música), almacenarlos dentro de una base de datos de lado del cliente y reproducirlos según sea necesario. El usuario solo tendría que descargar los archivos de música una vez; en las visitas posteriores, se recuperarían de la base de datos.

+ +
+

Nota: Existen límites en la cantidad de datos que puedes almacenar utilizando las APIs de almacenamiento de lado del cliente (posiblemente tanto por API individual como acumulativamente); el límite exacto varía según el navegador y posiblemente según la configuración del usuario. Consulta {{web.link("/es/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria", "límites de almacenamiento del navegador y criterios de desalojo")}} para obtener más información.

+
+ +

Vieja escuela: cookies

+ +

El concepto de almacenamiento de lado del cliente existe desde hace mucho tiempo. Desde los primeros días de la web, los sitios han utilizado {{web.link("/es/docs/Web/HTTP/Cookies", "cookies")}} para almacenar información y personalizar la experiencia del usuario en los sitios web. Son la forma más antigua de almacenamiento de lado del cliente que se usa comúnmente en la web.

+ +

En estos días, existen mecanismos más fáciles disponibles para almacenar datos de lado del cliente, por lo tanto, no te enseñaremos cómo usar las cookies en este artículo. Sin embargo, esto no significa que las cookies sean completamente inútiles en la web moderna; todavía se usan comúnmente para almacenar datos relacionados con la personalización y el estado del usuario, p. ej. ID de sesión y fragmentos de acceso. Para obtener más información sobre las cookies, consulta nuestro artículo {{web.link("/es/docs/Web/HTTP/Cookies", "Uso de cookies HTTP")}}.

+ +

Nueva escuela: almacenamiento web e IndexedDB

+ +

Las características "más fáciles" que mencionamos anteriormente son las siguientes:

+ + + +

Aprenderás más sobre estas APIs a continuación.

+ +

El futuro: API de caché

+ +

Algunos navegadores modernos admiten la nueva API {{domxref("Cache")}}. Esta API está diseñada para almacenar respuestas HTTP a solicitudes específicas y es muy útil para hacer cosas como almacenar activos del sitio web sin conexión para que el sitio se pueda usar posteriormente sin una conexión de red. La caché generalmente se usa en combinación con la {{web.link("/es/docs/Web/API/Service_Worker_API", "API del servicio Worker")}}, aunque no necesariamente tiene que ser así.

+ +

El uso de caché y el servicio Workers es un tema avanzado, y no lo cubriremos con gran detalle en este artículo, aunque mostraremos un ejemplo simple en la sección {{anch("Almacenamiento_de_activos_sin_conexion", "Almacenamiento de activos sin conexión")}} a continuación.

+ +

Almacenamiento de datos simples: almacenamiento web

+ +

La {{web.link("/es/docs/Web/API/Web_Storage_API", "API de almacenamiento web")}} es muy fácil de usar: almacena pares de datos simples de nombre/valor (limitado a cadenas, números, etc.) y recupera estos valores cuando sea necesario.

+ +

Sintaxis básica

+ +

Te mostramos como:

+ +
    +
  1. +

    Primero, ve a nuestra plantilla en blanco de almacenamiento web en GitHub (abre esto en una nueva pestaña).

    +
  2. +
  3. +

    Abre la consola JavaScript de las herramientas de desarrollo de tu navegador.

    +
  4. +
  5. +

    Todos tus datos de almacenamiento web están contenidos en dos estructuras similares a objetos dentro del navegador: {{domxref("Window.sessionStorage", "sessionStorage")}} y {{domxref("Window.localStorage", "localStorage")}}. El primero conserva los datos mientras el navegador está abierto (los datos se pierden cuando se cierra el navegador) y el segundo conserva los datos incluso después de que el navegador se cierra y luego se vuelve a abrir. Usaremos el segundo en este artículo, ya que generalmente es más útil.

    + +

    El método {{domxref("Storage.setItem()")}} te permite guardar un elemento de datos en el almacenamiento; toma dos parámetros: el nombre del elemento y su valor. Intenta escribir esto en tu consola de JavaScript (cambia el valor a tu propio nombre, si lo deseas):

    + +
    localStorage.setItem('nombre','Chris');
    +
  6. +
  7. +

    El método {{domxref("Storage.getItem()")}} toma un parámetro, el nombre de un elemento de datos que deseas recuperar, y devuelve el valor del elemento. Ahora escribe estas líneas en tu consola JavaScript:

    + +
    let miNombre = localStorage.getItem('nombre');
    +miNombre
    + +

    Al escribir en la segunda línea, deberías ver que la variable miNombre ahora contiene el valor del elemento de datos nombre.

    +
  8. +
  9. +

    El método {{domxref("Storage.removeItem()")}} toma un parámetro, el nombre de un elemento de datos que desea eliminar, y elimina ese elemento del almacenamiento web. Escribe las siguientes líneas en tu consola JavaScript:

    + +
    localStorage.removeItem('nombre');
    +let miNombre = localStorage.getItem('nombre');
    +miNombre
    + +

    La tercera línea ahora debería devolver null: el elemento nombre ya no existe en el almacenamiento web.

    +
  10. +
+ +

¡Los datos persisten!

+ +

Una característica clave del almacenamiento web es que los datos persisten entre las cargas de la página (e incluso cuando el navegador está apagado, en el caso de localStorage). Veamos esto en acción.

+ +
    +
  1. +

    Abre nuestra plantilla en blanco de almacenamiento web nuevamente, ¡pero esta vez en un navegador diferente al que tiene abierto este tutorial!; Esto hará que sea más fácil de manejar.

    +
  2. +
  3. +

    Escribe estas líneas en la consola JavaScript del navegador:

    + +
    localStorage.setItem('nombre','Chris');
    +let miNombre = localStorage.getItem('nombre');
    +miNombre
    + +

    Deberías ver el nombre del elemento devuelto.

    +
  4. +
  5. +

    Ahora cierre el navegador y ábrelo de nuevo.

    +
  6. +
  7. +

    Ingresa las siguientes líneas nuevamente:

    + +
    let miNombre = localStorage.getItem('nombre');
    +miNombre
    + +

    Deberías ver que el valor aún está disponible, aunque el navegador se haya cerrado y luego se haya abierto nuevamente.

    +
  8. +
+ +

Almacenamiento independiente para cada dominio

+ +

Hay un almacén de datos separado para cada dominio (cada dirección web separada cargada en el navegador). Verás que si cargas dos sitios web (por ejemplo, google.com y amazon.com) e intentas almacenar un elemento en un sitio web, no estará disponible para el otro sitio web.

+ +

Esto tiene sentido: ¿puedes imaginar los problemas de seguridad que surgirían si los sitios web pudieran ver los datos de los demás?

+ +

Un ejemplo más complicado

+ +

Apliquemos este conocimiento recién descubierto escribiendo un sencillo ejemplo para darte una idea de cómo se puede usar el almacenamiento web. Nuestro ejemplo te permitirá ingresar un nombre, luego de lo cual la página se actualizará para darte un saludo personalizado. Este estado también persistirá en las recargas de la página/navegador, porque el nombre se guarda en el almacenamiento web.

+ +

Puede encontrar el HTML de ejemplo en personal-greeting.html: contiene un sitio web simple con un encabezado, contenido y pie de página, y un formulario para ingresar tu nombre.

+ +

Ejemplo de almacenamiento

+ +

Construyamos el ejemplo para que puedas entender cómo funciona.

+ +
    +
  1. +

    Primero, haz una copia local de nuestro archivo personal-greeting.html en un nuevo directorio en tu computadora.

    +
  2. +
  3. +

    A continuación, observa cómo nuestro HTML hace referencia a un archivo JavaScript llamado index.js (ve la línea 40). Necesitamos crearlo y escribir nuestro código JavaScript en él. Cree un archivo index.js en el mismo directorio que tu archivo HTML.

    +
  4. +
  5. +

    Comenzaremos creando referencias a todas las características HTML que necesitamos manipular en este ejemplo; las crearemos todas como constantes, ya que estas referencias no necesitan cambiar en el ciclo de vida de la aplicación. Agrega las siguientes líneas a tu archivo JavaScript:

    + +
    // crea las constantes necesarias
    +const rememberDiv = document.querySelector('.remember');
    +const forgetDiv = document.querySelector('.forget');
    +const form = document.querySelector('form');
    +const nameInput = document.querySelector('#entername');
    +const submitBtn = document.querySelector('#submitname');
    +const forgetBtn = document.querySelector('#forgetname');
    +
    +const h1 = document.querySelector('h1');
    +const personalGreeting = document.querySelector('.personal-greeting');
    +
  6. +
  7. +

    A continuación, necesitamos incluir un pequeño escucha de eventos para evitar que el formulario se envíe cuando se presiona el botón de envío, ya que este no es el comportamiento que queremos. Agrega este fragmento debajo de tu código anterior:

    + +
    // Evita que el formulario se envíe cuando se presiona un botón
    +form.addEventListener('submit', function(e) {
    +  e.preventDefault();
    +});
    +
  8. +
  9. +

    Ahora necesitamos agregar un escucha de eventos, cuya función controladora se ejecutará cuando se haga clic en el botón "Saludar". Los comentarios explican en detalle qué hace cada bit, pero en esencia aquí tomamos el nombre que el usuario ingresó en el cuadro de entrada de texto y lo guardamos en el almacenamiento web usando setItem(), luego ejecutamos una función llamada nameDisplayCheck() que se encargará de actualizar el texto real del sitio web. Agrega esto al final de tu código:

    + +
    // ejecuta la función cuando se hace clic en el botón 'Saludar'
    +submitBtn.addEventListener('click', function() {
    +  // guarda el nombre ingresado en el almacenamiento web
    +  localStorage.setItem('name', nameInput.value);
    +  // ejecuta nameDisplayCheck() para ordenar la visualización del
    +  // saludo personalizado y actualización de la visualización del formulario
    +  nameDisplayCheck();
    +});
    +
  10. +
  11. +

    En este punto, también necesitamos un controlador de eventos para ejecutar una función cuando se hace clic en el botón "Olvidar"; esto solo se muestra después de hacer clic en el botón "Saludar" (los dos estados del formulario se alternan hacia adelante y hacia atrás). En esta función, eliminamos el elemento name del almacenamiento web usando removeItem(), luego ejecutamos nuevamente nameDisplayCheck() para actualizar la pantalla. Agrega esto al final:

    + +
    // ejecuta la función cuando se hace clic en el botón 'Olvidar'
    +forgetBtn.addEventListener('click', function() {
    +  // Elimina el nombre guardado del almacenamiento web
    +  localStorage.removeItem('nombre');
    +  // ejecuta nameDisplayCheck() para ordenar la visualización del
    +  // saludo genérico nuevamente y actualiza la visualización del formulario
    +  nameDisplayCheck();
    +});
    +
  12. +
  13. +

    Ahora es el momento de definir la propia función nameDisplayCheck(). Aquí verificamos si el elemento de nombre se ha guardado en el almacenamiento web utilizando localStorage.getItem('name') como prueba condicional. Si se ha guardado, esta llamada se evaluará como true; si no, será false. Si es true, mostramos un saludo personalizado, mostramos la parte "Olvidar" del formulario y ocultamos la parte "Saludar" del formulario. Si es false, mostramos un saludo genérico y hacemos lo contrario. Nuevamente, pon el siguiente código en la parte inferior:

    + +
    // definir la función nameDisplayCheck()
    +function nameDisplayCheck() {
    +  // verifica si el elemento de datos 'name' está guardado en el almacenamiento web
    +  if(localStorage.getItem('name')) {
    +    // Si es así, muestra un saludo personalizado
    +    let name = localStorage.getItem('name');
    +    h1.textContent = 'Bienvenido, ' + name;
    +    personalGreeting.textContent = '¡Bienvenido a nuestro sitio web, ' + name + '! Esperamos que te diviertas mientras estés aquí.';
    +    // ocultar la parte 'recordar' del formulario y mostrar la parte 'olvidar'
    +    forgetDiv.style.display = 'block';
    +    rememberDiv.style.display = 'none';
    +  } else {
    +    // si no, muestra un saludo genérico
    +    h1.textContent = 'Bienvenido a nuestro sitio web ';
    +    personalGreeting.textContent = 'Bienvenido a nuestro sitio web. Esperamos que se diviertas mientras estés aquí.';
    +    // ocultar la parte 'olvidar' del formulario y mostrar la parte 'recordar'
    +    forgetDiv.style.display = 'none';
    +    rememberDiv.style.display = 'block';
    +  }
    +}
    +
  14. +
  15. +

    Por último, pero no menos importante, debemos ejecutar la función nameDisplayCheck() cada vez que se carga la página. Si no hacemos esto, el saludo personalizado no persistirá en las recargas de la página. Agrega lo siguiente al final de tu código:

    + +
    document.body.onload = nameDisplayCheck;
    +
  16. +
+ +

Tu ejemplo está terminado, ¡bien hecho!; Todo lo que queda ahora es guardar tu código y probar tu página HTML en un navegador. Puedes ver nuestra versión finalizada en vivo aquí.

+ +
+

Nota: Hay otro ejemplo un poco más complejo para explorar en {{web.link("/es/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API", "Uso de la API de almacenamiento web")}}.

+
+ +
+

Nota: En la línea <script src="index.js" defer></script> del código fuente de nuestra versión final, el atributo defer especifica que el contenido del elemento {{htmlelement("script")}} no se ejecutará hasta que la página haya terminado de cargarse.

+
+ +

Almacenamiento de datos complejos — IndexedDB

+ +

La {{web.link("/es/docs/Web/API/IndexedDB_API", "API IndexedDB")}} (a veces abreviada IDB) es un sistema de base de datos completo disponible en el navegador en el que puedes almacenar datos complejos relacionados, tipos de los cuales no se limitan a valores simples como cadenas o números. Puedes almacenar videos, imágenes y casi cualquier otra cosa en una instancia de IndexedDB.

+ +

Sin embargo, esto tiene un costo: IndexedDB es mucho más complejo de usar que la API de almacenamiento web. En esta sección, solo vamos a arañar la superficie de lo que es capaz de hacer, pero te daremos lo suficiente para comenzar.

+ +

Trabajar con un ejemplo de almacenamiento de notas

+ +

Aquí, mostraremos un ejemplo que te permite almacenar notas en tu navegador y verlas y eliminarlas cuando lo desees, lo cual te permitirá crearlo tú mismo y explicar las partes más fundamentales del IDB a medida que avanzamos.

+ +

La aplicación se parece a esta:

+ +

IDB en acción

+ +

Cada nota tiene un título y un cuerpo de texto, cada uno editable individualmente. El código JavaScript que veremos a continuación tiene comentarios detallados para ayudarte a comprender lo que está sucediendo.

+ +

Primeros pasos

+ +
    +
  1. En primer lugar, haz copias locales de nuestros archivos index.html, style.css y index-start.js en un nuevo directorio en tu máquina.
  2. +
  3. Échale un vistazo a los archivos. Verás que el HTML es bastante simple: un sitio web con encabezado y pie de página, así como un área de contenido principal que contiene un lugar para mostrar notas y un formulario para ingresar nuevas notas en la base de datos. El CSS proporciona un estilo simple para aclarar lo que está sucediendo. El archivo JavaScript contiene cinco constantes declaradas que contienen referencias al elemento {{htmlelement("ul")}} en el que se mostrarán las notas, el título y el cuerpo de elementos {{htmlelement("input")}}, el {{htmlelement("form")}} en sí mismo, y el {{htmlelement("button")}}.
  4. +
  5. Cambia el nombre de tu archivo JavaScript a index.js. Ahora estás listo para comenzar a agregarle código.
  6. +
+ +

Configuración inicial de la base de datos

+ +

Ahora veamos lo que tenemos que hacer en primer lugar, para configurar una base de datos.

+ +
    +
  1. +

    Debajo de las declaraciones constantes, agrega las siguientes líneas:

    + +
    // Crea una instancia de un objeto db para que almacenemos la base de datos abierta
    +let db;
    + +

    Aquí estamos declarando una variable llamada db, que luego se usará para almacenar un objeto que representa nuestra base de datos. Usaremos esto en algunos lugares, por lo que hemos declarado globalmente aquí para facilitar las cosas.

    +
  2. +
  3. +

    A continuación, agrega lo siguiente al final de tu código:

    + +
    window.onload = function() {
    +
    +};
    + +

    Escribiremos todo nuestro subsiguiente código dentro de esta función controladora de eventos window.onload, llamada cuando se activa el evento {{event("load")}} de la ventana, para asegurarnos de que no intentemos usar la funcionalidad IndexedDB antes de que la aplicación haya terminado de cargarse por completo (podría fallar si no lo hacemos).

    +
  4. +
  5. +

    Dentro del controlador window.onload, agrega lo siguiente:

    + +
    // Abre nuestra base de datos; se crea si aún no existe
    +// (ve onupgradeneeded a continuación)
    +let request = window.indexedDB.open('notes_db', 1);
    + +

    Esta línea crea una solicitud para abrir la versión 1 de una base de datos llamada notes_db. Si esta aún no existe, se creará para ti mediante un código posterior. Verás que este patrón de solicitud se usa con mucha frecuencia en IndexedDB. Las operaciones de la base de datos llevan tiempo. No deseas colgar el navegador mientras esperas los resultados, por lo que las operaciones de la base de datos son {{Glossary("asíncronas")}}, lo que significa que en lugar de ocurrir de inmediato, sucederán en algún momento en el futuro, y recibirás una notificación cuando haya terminado.

    + +

    Para manejar esto en IndexedDB, crea un objeto de solicitud (que se puede llamar como desees; lo llamamos request, por lo que es obvio para qué sirve). Luego, usa controladores de eventos para ejecutar código cuando la solicitud se completa, falla, etc., que verás en uso a continuación.

    + +
    +

    Nota: El número de versión es importante. Si deseas actualizar tu base de datos (por ejemplo, cambiando la estructura de la tabla), debes ejecutar tu código nuevamente con un número de versión aumentado, un esquema diferente especificado dentro del controlador onupgradeneeded (ve más abajo), etc. No cubriremos la actualización de bases de datos en este sencillo tutorial.

    +
    +
  6. +
  7. +

    Ahora agrega los siguientes controladores de eventos justo debajo de tu adición anterior, nuevamente dentro del controlador window.onload:

    + +
    // un controlador de error significa que la base de datos no se abrió correctamente
    +request.onerror = function() {
    +  console.log('No se pudo abrir la base de datos');
    +};
    +
    +// controlador onsuccess significa que la base de datos se abrió correctamente
    +request.onsuccess = function() {
    +  console.log('Base de datos abierta con éxito');
    +
    +  // Almacena el objeto de base de datos abierto en la variable db. Esto se usa mucho a continuación
    +  db = request.result;
    +
    +  // Ejecute la función displayData() para mostrar las notas que ya están en la IDB
    +  displayData();
    +};
    + +

    El controlador {{domxref("IDBRequest.onerror", "request.onerror")}} se ejecutará si el sistema dice que la solicitud falló. Esto te permite responder a este problema. En nuestro sencillo ejemplo, simplemente imprimimos un mensaje en la consola de JavaScript.

    + +

    El controlador {{domxref("IDBRequest.onsuccess", "request.onsuccess")}} por otro lado se ejecutará si la solicitud regresa con éxito, lo que significa que la base de datos se abrió correctamente. Si este es el caso, un objeto que representa la base de datos abierta pasa a estar disponible en la propiedad {{domxref("IDBRequest.result", "request.result")}}, lo que nos permite manipular la base de datos. Almacenamos esto en la variable db que creamos anteriormente para su uso posterior. También ejecutamos una función personalizada llamada displayData(), que muestra los datos en la base de datos dentro de {{HTMLElement("ul")}}. Lo ejecutamos ahora para que las notas que ya están en la base de datos se muestren tan pronto como se cargue la página. Verás esto definido más adelante.

    +
  8. +
  9. +

    Finalmente, en esta sección, agregaremos probablemente el controlador de eventos más importante para configurar la base de datos: {{domxref("IDBOpenDBRequest.onupgradeneeded", "request.onupgradeneeded")}}. Este controlador se ejecuta si la base de datos aún no se ha configurado, o si la base de datos se abre con un número de versión mayor que la base de datos almacenada existente (al realizar una actualización). Agrega el siguiente código, debajo de tu controlador anterior:

    + +
    // Configura las tablas de la base de datos si esto aún no se ha hecho
    +request.onupgradeneeded = function(e) {
    +  // Toma una referencia a la base de datos abierta
    +  let db = e.target.result;
    +
    +  // Crea un objectStore para almacenar nuestras notas (básicamente como una sola tabla)
    +  // incluyendo una clave de incremento automático
    +  let objectStore = db.createObjectStore('notes_os', {keyPath: 'id', autoIncrement: true});
    +
    +  // Define qué elementos de datos contendrá el objectStore
    +  objectStore.createIndex('title', 'title', { unique: false });
    +  objectStore.createIndex('body', 'body', { unique: false });
    +
    +  console.log('Configuración de la base de datos completa');
    +};
    + +

    Aquí es donde definimos el esquema (estructura) de nuestra base de datos; es decir, el conjunto de columnas (o campos) que contiene. Aquí primero tomamos una referencia a la base de datos existente de la propiedad result del objetivo del evento (e.target.result), que es el objeto request. Esto es equivalente a la línea db = request.result; dentro del controlador onsuccess, pero aquí, debemos hacer esto por separado porque el controlador onupgradeneeded (si es necesario) se ejecutará antes que el controlador onsuccess, lo que significa que el valor db no estaría disponible si no hiciéramos esto.

    + +

    Luego usamos {{domxref("IDBDatabase.createObjectStore()")}} para crear un nuevo almacén de objetos dentro de nuestra base de datos abierta llamada notes_os. Esto es equivalente a una sola tabla en un sistema de base de datos convencional. Le hemos dado el nombre notas, y también hemos especificado un campo clave autoIncrement llamado id — en cada nuevo registro se le dará automáticamente un valor incrementado — el desarrollador no lo hace No es necesario establecer esto explícitamente. Al ser la clave, el campo id se utilizará para identificar registros de forma única, como cuando se elimina o muestra un registro.

    + +

    También creamos otros dos índices (campos) usando el método {{domxref("IDBObjectStore.createIndex()")}}: title (que contendrá un título para cada nota) y body (que contendrá el texto del cuerpo de la nota).

    +
  10. +
+ +

Entonces, con este esquema de base de datos simple configurado, cuando comenzamos a agregar registros a la base de datos; cada uno se representará como un objeto siguiendo estas líneas:

+ +
{
+  title: "Compra leche",
+  body: "Necesita leche de vaca y soja",
+  id: 8
+}
+ +

Agregar datos a la base de datos

+ +

Ahora veamos cómo podemos agregar registros a la base de datos. Esto se hará mediante el formulario de nuestra página.

+ +

Debajo de tu controlador de eventos anterior (pero aún dentro del controlador window.onload), agrega la siguiente línea, que configura un controlador onsubmit que ejecuta una función llamada addData() cuando se envía el formulario (cuando se presiona el {{htmlelement("button")}} de enviar, lo que lleva a un envío exitoso del formulario):

+ +
// Crea un controlador onsubmit para que cuando se envíe el formulario se ejecute la función addData()
+form.onsubmit = addData;
+ +

Ahora definamos la función addData(). Agrega esto debajo de tu línea anterior:

+ +
// Define la función addData()
+function addData(e) {
+  // evitar el predeterminado: no queremos que el formulario se envíe de la forma convencional
+  e.preventDefault();
+
+  // toma los valores ingresados en los campos del formulario y los almacenar en un objeto listo para ser insertado en la base de datos
+  let newItem = { title: titleInput.value, body: bodyInput.value };
+
+  // abre una transacción de base de datos de lectura/escritura, lista para agregar los datos
+  let transaction = db.transaction(['notes_os'], 'readwrite');
+
+  // llama a un almacén de objetos que ya se ha agregado a la base de datos
+  let objectStore = transaction.objectStore('notes_os');
+
+  // Hacer una solicitud para agregar nuestro objeto newItem al almacén de objetos
+  let request = objectStore.add(newItem);
+  request.onsuccess = function() {
+    // Limpiar el formulario, listo para agregar la siguiente entrada
+    titleInput.value = '';
+    bodyInput.value = '';
+  };
+
+  // Informa sobre el éxito de la transacción completada, cuando todo esté hecho
+  transaction.oncomplete = function() {
+    console.log('Transacción completada: modificación de la base de datos finalizada.');
+
+    // actualiza la visualización de datos para mostrar el elemento recién agregado, ejecutando displayData() nuevamente.
+    displayData();
+  };
+
+  transaction.onerror = function() {
+    console.log('Transacción no abierta debido a error');
+  };
+}
+ +

Esto es bastante complejo; desglosándolo, podemos:

+ + + +

Visualización de los datos

+ +

Ya hemos hecho referencia a displayData() dos veces en nuestro código, por lo que probablemente sea mejor definirla. Agrega esto a tu código, debajo de la definición de función anterior:

+ +
// Define la función displayData()
+function displayData() {
+  // Aquí vaciamos el contenido del elemento de la lista cada vez que se actualiza la pantalla
+  // Si no hiciste esto, obtendrás duplicados en la lista cada vez que se agregue una nueva nota
+  while (list.firstChild) {
+    list.removeChild(list.firstChild);
+  }
+
+  // Abre el almacén de objetos y luego obtiene un cursor, que recorre todos los
+  // diferentes elementos de datos en el almacén
+  let objectStore = db.transaction('notes_os').objectStore('notes_os');
+  objectStore.openCursor().onsuccess = function(e) {
+    // Obtiene una referencia al cursor
+    let cursor = e.target.result;
+
+    // Si todavía hay otro elemento de datos para iterar, sigue ejecutando este código
+    if(cursor) {
+      // Crea un elemento de lista, h3 y p para poner cada elemento de datos dentro al mostrarlo
+      // estructura el fragmento HTML y lo anexa dentro de la lista
+      const listItem = document.createElement('li');
+      const h3 = document.createElement('h3');
+      const para = document.createElement('p');
+
+      listItem.appendChild(h3);
+      listItem.appendChild(para);
+      list.appendChild(listItem);
+
+      // Coloca los datos del cursor dentro de h3 y para
+      h3.textContent = cursor.value.title;
+      para.textContent = cursor.value.body;
+
+      // Almacena el ID del elemento de datos dentro de un atributo en listItem, para que sepamos
+      // a qué elemento corresponde. Esto será útil más adelante cuando queramos eliminar elementos.
+      listItem.setAttribute('data-note-id', cursor.value.id);
+
+      // Crea un botón y lo coloca dentro de cada listItem
+      const deleteBtn = document.createElement('button');
+      listItem.appendChild(deleteBtn);
+      deleteBtn.textContent = 'Delete';
+
+      // Establece un controlador de eventos para que cuando se hace clic en el botón, el elemento deleteItem()
+      // se ejecuta la función
+      deleteBtn.onclick = deleteItem;
+
+      // Iterar al siguiente elemento del cursor
+      cursor.continue();
+    } else {
+      // Nuevamente, si el elemento de la lista está vacío, muestra el mensaje 'No hay notas almacenadas'
+      if(!list.firstChild) {
+        const listItem = document.createElement('li');
+        listItem.textContent = 'No hay notas almacenadas.';
+        list.appendChild(listItem);
+      }
+      // si no hay más elementos de cursor para iterar, dilo
+      console.log('Se muestran todas las notas');
+    }
+  };
+}
+ +

De nuevo, analicemos esto:

+ + + +

Eliminar una nota

+ +

Como se indicó anteriormente, cuando se presiona el botón de eliminación de una nota, la nota se elimina. Esto se logra mediante la función deleteItem(), que se ve así:

+ +
// Define la función deleteItem()
+function deleteItem(e) {
+  // recuperamos el nombre de la tarea que queremos eliminar. Necesitamos
+  // convertirla en un número antes de intentarla úselo con IDB; Clave del IDB
+  // los valores son sensibles al tipo.
+  let noteId = Number(e.target.parentNode.getAttribute('data-note-id'));
+
+  // abre una transacción de base de datos y elimina la tarea, encontrándola usando la identificación que obtuvimos arriba
+  let transaction = db.transaction(['notes_os'], 'readwrite');
+  let objectStore = transaction.objectStore('notes_os');
+  let request = objectStore.delete(noteId);
+
+  // informa que el elemento de datos ha sido eliminado
+  transaction.oncomplete = function() {
+    // elimina el padre del botón
+    // que es el elemento de la lista, por lo que ya no se muestra
+    e.target.parentNode.parentNode.removeChild(e.target.parentNode);
+    console.log('Nota ' + noteId + ' eliminada.');
+
+    // Nuevamente, si el elemento de la lista está vacío, muestra el mensaje 'No hay notas almacenadas'
+    if(!list.firstChild) {
+      let listItem = document.createElement('li');
+      listItem.textContent = 'No hay notas almacenadas.';
+      list.appendChild(listItem);
+    }
+  };
+}
+ + + +

¡Eso es todo!; Tu ejemplo debería funcionar ahora.

+ +

Si tienes problemas con él, no dudes en compararlo con nuestro ejemplo en vivo (consulta el código fuente también).

+ +

Almacenamiento de datos complejos a través de IndexedDB

+ +

Como mencionamos anteriormente, IndexedDB se puede usar para almacenar más que simples cadenas de texto. Puedes almacenar casi cualquier cosa que desees, incluidos objetos complejos como blobs de imágenes o vídeos. Y no es mucho más difícil de conseguir que cualquier otro tipo de dato.

+ +

Para demostrar cómo hacerlo, hemos escrito otro ejemplo llamado almacenaje de videos con IndexedDB (verlo en vivo aquí también). Cuando ejecutas el ejemplo por primera vez, descarga todos los videos de la red, los almacena en una base de datos IndexedDB y luego muestra los videos en la IU dentro de los elementos {{htmlelement("video")}}. La segunda vez que lo ejecutas, encuentra los videos en la base de datos y los obtiene de allí antes de mostrarlos; esto hace que las cargas posteriores sean mucho más rápidas y menos necesitadas de ancho de banda.

+ +

Repasemos las partes más interesantes del ejemplo. No lo veremos todo; gran parte es similar al ejemplo anterior y el código está bien comentado.

+ +
    +
  1. +

    Para este ejemplo simple, hemos almacenado los nombres de los videos para buscarlos en un arreglo de objetos:

    + +
    const videos = [
    +  { 'name' : 'crystal' },
    +  { 'name' : 'elf' },
    +  { 'name' : 'frog' },
    +  { 'name' : 'monster' },
    +  { 'name' : 'pig' },
    +  { 'name' : 'rabbit' }
    +];
    +
  2. +
  3. +

    Para empezar, una vez que la base de datos se abre con éxito, ejecutamos una función init(). Esto recorre los diferentes nombres de video, tratando de cargar un registro identificado por cada nombre de la base de datos de videos.

    + +

    Si cada video se encuentra en la base de datos (se verifica fácilmente al ver si request.result se evalúa como true; si el registro no está presente, será undefined), sus archivos de video (almacenados como blobs) y el nombre del video se pasan directamente a la función displayVideo() para colocarlos en la interfaz de usuario. De lo contrario, el nombre del video se pasa a la función fetchVideoFromNetwork() para ... ¡adivinaste!: recupera el video de la red.

    + +
    function init() {
    +  // Recorre los nombres de los videos uno por uno
    +  for(let i = 0; i < videos.length; i++) {
    +    // Abre la transacción, obtiene objetos del almacén y get() cada video por nombre
    +    let objectStore = db.transaction('videos_os').objectStore('videos_os');
    +    let request = objectStore.get(videos[i].name);
    +    request.onsuccess = function() {
    +      // Si el resultado existe en la base de datos (no está indefinido)
    +      if(request.result) {
    +        // Toma los videos del IDB y los muestra usando displayVideo()
    +        console.log('tomando videos del IDB');
    +        displayVideo(request.result.mp4, request.result.webm, request.result.name);
    +      } else {
    +        // Recuperar los videos de la red
    +        fetchVideoFromNetwork(videos[i]);
    +      }
    +    };
    +  }
    +}
    +
  4. +
  5. +

    El siguiente fragmento se tomó del interior de fetchVideoFromNetwork() — aquí obtenemos las versiones MP4 y WebM del video usando dos peticiones {{domxref("fetch()", "WindowOrWorkerGlobalScope.fetch()")}}. Luego usamos el método {{domxref("blob()", "Body.blob()")}} para extraer el cuerpo de cada respuesta como un blob, dándonos una representación de objeto de los videos que se pueden almacenar y mostrar más adelante.

    + +

    Sin embargo, tenemos un problema aquí: estas dos solicitudes son asíncronas, pero solo queremos intentar mostrar o almacenar el video cuando ambas promesas se hayan cumplido. Afortunadamente, hay un método incorporado que maneja este problema: {{jsxref("Promise.all()")}}. Este toma un argumento, referencias a todas las promesas individuales que deseas verificar para su cumplimiento colocadas en un arreglo, y en sí mismo se basa en promesas.

    + +

    Cuando todas esas promesas se han cumplido, la promesa all() se cumple con un arreglo que contiene todos los valores de cumplimiento individuales. Dentro del bloque all(), puedes ver que luego llamamos a la función displayVideo() como lo hicimos antes para mostrar los videos en la interfaz de usuario, luego también llamamos a la función storeVideo() para almacenar esos videos dentro de la base de datos.

    + +
    let mp4Blob = fetch('videos/' + video.name + '.mp4').then(response =>
    +  response.blob()
    +);
    +let webmBlob = fetch('videos/' + video.name + '.webm').then(response =>
    +  response.blob()
    +);
    +
    +// Ejecuta el siguiente código solo cuando se hayan cumplido ambas promesas
    +Promise.all([mp4Blob, webmBlob]).then(function(values) {
    +  // muestra el video obtenido de la red con displayVideo()
    +  displayVideo(values[0], values[1], video.name);
    +  // lo almacena en el IDB usando storeVideo()
    +  storeVideo(values[0], values[1], video.name);
    +});
    +
  6. +
  7. +

    Veamos primero storeVideo(). Esto es muy similar al patrón que viste en el ejemplo anterior para agregar datos a la base de datos: abrimos una transacción readwrite y obtenemos una referencia a nuestro almacén de objetos videos_os, creamos un objeto que representa el registro para agregar a la base de datos, luego simplemente lo agrega usando {{domxref("IDBObjectStore.add()")}}.

    + +
    función storeVideo(mp4Blob, webmBlob, nombre) {
    +  // Abre transacción, obtiene el almacén de objetos; lo convierte en lectura y escritura para que podamos escribir en el IDB
    +  let objectStore = db.transaction(['videos_os'], 'readwrite').objectStore('videos_os');
    +  // Crea un registro para agregar al IDB
    +  let record = {
    +    mp4 : mp4Blob,
    +    webm : webmBlob,
    +    name : name
    +  }
    +
    +  // Agrega el registro al IDB usando add()
    +  let request = objectStore.add(record);
    +
    +  ...
    +
    +};
    +
  8. +
  9. +

    Por último, pero no menos importante, tenemos displayVideo(), que crea los elementos DOM necesarios para insertar el video en la interfaz de usuario y luego los agrega a la página. Las partes más interesantes de esto son las que se muestran a continuación: para mostrar realmente nuestros blobs de video en un elemento <video>, necesitamos crear URL de objeto (URL internas que apuntan a los blobs de video almacenados en la memoria) utilizando el método {{domxref("URL.createObjectURL()")}}. Una vez hecho esto, podemos configurar las URL del objeto para que sean los valores de los atributos src de nuestro elemento {{htmlelement("source")}}, y funciona bien.

    + +
    function displayVideo(mp4Blob, webmBlob, title) {
    +  // Crea URL del objeto a partir de blobs
    +  let mp4URL = URL.createObjectURL(mp4Blob);
    +  let webmURL = URL.createObjectURL(webmBlob);
    +
    +  ...
    +
    +  const video = document.createElement('video');
    +  video.controls = true;
    +  const source1 = document.createElement('source');
    +  source1.src = mp4URL;
    +  source1.type = 'video/mp4';
    +  const source2 = document.createElement('source');
    +  source2.src = webmURL;
    +  source2.type = 'video/webm';
    +
    +  ...
    +}
    +
  10. +
+ +

Almacenamiento de activos sin conexión

+ +

El ejemplo anterior ya muestra cómo crear una aplicación que almacenará grandes activos en una base de datos IndexedDB, evitando la necesidad de descargarlos más de una vez. Esto ya es una gran mejora para la experiencia del usuario, pero todavía falta una cosa: los archivos HTML, CSS y JavaScript principales aún se deben descargar cada vez que se accede al sitio, lo cual significa que no funcionará cuando no haya conexión de red.

+ +

Fuera de línea

+ +

Aquí es donde entran el {{web.link("/es/docs/Web/API/Service_Worker_API", "servicio workers")}} y la {{web.link("/es/docs/Web/API/Cache", "API de caché")}}.

+ +

Un servicio worker es un archivo JavaScript que, en pocas palabras, se registra con un origen en particular (sitio web o parte de un sitio web en un determinado dominio) cuando se accede a él mediante un navegador. Cuando se registra, puede controlar las páginas disponibles en ese origen. Para ello, se sienta entre una página cargada y la red e intercepta las solicitudes de red dirigidas a ese origen.

+ +

Cuando intercepta una solicitud, puede hacer lo que desees (consulta {{web.link("/es/docs/Web/API/Service_Worker_API#Other_use_case_ideas", "ideas de casos de uso")}}), pero el ejemplo clásico es guardar las respuestas de la red fuera de línea y luego proporcionarlas en respuesta a una solicitud en lugar de las respuestas de la red. De hecho, te permite hacer que un sitio web funcione completamente fuera de línea.

+ +

La API de caché es otro mecanismo de almacenamiento del lado del cliente, con una pequeña diferencia: está diseñada para guardar respuestas HTTP y, por lo tanto, funciona muy bien con el servicio workers.

+ +
+

Nota: El servicio workers y la memoria caché ahora son compatibles con la mayoría de los navegadores modernos. Al momento de escribir este artículo, Safari todavía estaba ocupado implementándolo, pero debería estar allí pronto.

+
+ +

Un ejemplo del servicio worker

+ +

Veamos un ejemplo para darte una idea de cómo se vería esto. Hemos creado otra versión del ejemplo del almacén de videos que vimos en la sección anterior; este funciona de manera idéntica, excepto que también guarda HTML, CSS y JavaScript en la API de caché a través de un servicio worker, lo que permite que el ejemplo se ejecute sin conexión.

+ +

Ve almacén de videos IndexedDB con servicio worker funcionando en vivo y también ve el código fuente.

+ +

Registrar el servicio worker

+ +

Lo primero que hay que tener en cuenta es que hay un fragmento adicional de código colocado en el archivo JavaScript principal (consulta index.js). Primero hacemos una prueba de detección de características para ver si el miembro serviceWorker está disponible en el objeto {{domxref("Navigator")}}. Si esto devuelve true, entonces sabemos que al menos se respaldan los conceptos básicos del servicio workers. Aquí adentro usamos el método {{domxref("ServiceWorkerContainer.register )")}} para registrar un servicio worker contenido en el archivo sw.js contra el origen en el que reside, para que pueda controlar páginas en el mismo directorio que él, o subdirectorios. Cuando se cumple su promesa, el trabajador del servicio se considera registrado.

+ +
  // Registrar el servicio workers para controlar que el sitio funcione sin conexión
+
+  if('serviceWorker' in navigator) {
+    navigator.serviceWorker
+             .register('/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js')
+             .then(function() { console.log('Servicio Worker Registrado'); });
+  }
+ +
+

Nota: La ruta proporcionada al archivo sw.js es relativa al origen del sitio, no al archivo JavaScript que contiene el código. El servicio worker está en https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js. El origen es https://mdn.github.io y, por lo tanto, la ruta dada debe ser /learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js. Si quisieras alojar este ejemplo en tu propio servidor, tendrías que cambiarlo consecuentemente. Esto es bastante confuso, pero tiene que funcionar de esta manera por razones de seguridad.

+
+ +

Instalación del servicio worker

+ +

La próxima vez que se accede a cualquier página bajo el control del servicio worker (por ejemplo, cuando se vuelve a cargar el ejemplo), el servicio worker se instala en esa página, lo cual significa que comenzará a controlarla. Cuando esto ocurre, se dispara un evento install contra el servicio worker; puedes escribir código dentro del propio servicio worker que responderá a la instalación.

+ +

Veamos un ejemplo, en el archivo sw.js (el servicio worker). Verás que el detector de instalación está registrado en self. Esta palabra clave self es una forma de hacer referencia al alcance global del servicio worker desde el interior del archivo del servicio worker.

+ +

Dentro del controlador install usamos el método {{domxref("ExtendableEvent.waitUntil()")}}, disponible en el objeto event, para indicar que el navegador no debe completar la instalación del servicio worker hasta que la promesa interior se haya cumplido con éxito.

+ +

Aquí es donde vemos en acción la API de Cache. Usamos el método {{domxref("CacheStorage.open()")}} para abrir un nuevo objeto Cache en el que se pueden almacenar las respuestas (similar a un almacén de objetos IndexedDB). Esta promesa se cumple con un objeto {{domxref("Cache")}} que representa la caché de video-store. Luego usamos el método {{domxref("Cache.addAll()")}} para obtener una serie de activos y agregar sus respuestas a la caché.

+ +
self.addEventListener('install', function(e) {
+ e.waitUntil(
+   caches.open('video-store').then(function(cache) {
+     return cache.addAll([
+       '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/',
+       '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.html',
+       '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.js',
+       '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/style.css'
+     ]);
+   })
+ );
+});
+ +

Eso es todo por ahora, instalación terminada.

+ +

Responder a más solicitudes

+ +

Con el servicio worker registrado e instalado en nuestra página HTML, y todos los activos relevantes agregados a nuestra caché, estamos casi listos para comenzar. Solo queda una cosa más por hacer, escribir código para responder a más solicitudes de red.

+ +

Esto es lo que hace el segundo bit de código en sw.js. Agregamos otro escucha al ámbito global del servicio worker, que ejecuta la función del controlador cuando se genera el evento fetch. Esto sucede cada vez que el navegador solicita un activo en el directorio en el que está registrado el servicio worker.

+ +

Dentro del controlador, primero registramos la URL del activo solicitado. Luego proporcionamos una respuesta personalizada a la solicitud, utilizando el método {{domxref("FetchEvent.respondWith()")}}.

+ +

Dentro de este bloque usamos {{domxref("CacheStorage.match()")}} para verificar si una solicitud coincidente (es decir, coincide con la URL) se puede encontrar en cualquier caché. Esta promesa se cumple con la respuesta coincidente si se encuentra una coincidencia, o undefined si no lo es.

+ +

Si se encuentra una coincidencia, simplemente la devolvemos como la respuesta personalizada. De lo contrario, {{web.link("/es/docs/Web/API/WindowOrWorkerGlobalScope/fetch", "fetch()")}} la respuesta de la red y la devolvemos en su lugar.

+ +
self.addEventListener('fetch', function(e) {
+  console.log(e.request.url);
+  e.respondWith(
+    caches.match(e.request).then(function(response) {
+      return response || fetch(e.request);
+    })
+  );
+});
+ +

Y eso es todo para nuestro sencillo servicio worker. Hay muchas más cosas que puedes hacer con ellos; para obtener más detalles, consulta el libro de recetas para el servicio worker. Y gracias a Paul Kinlan por su artículo Agregar un servicio worker y sin conexión a tu aplicación web, que inspiró este sencillo ejemplo.

+ +

Probando el ejemplo sin conexión

+ +

Para probar nuestro ejemplo de servicio worker, deberás cargarlo un par de veces para asegurarte de que esté instalado. Una vez hecho esto, puedes:

+ + + +

Si actualizas tu página de ejemplo nuevamente, deberías ver que se carga bien. Todo se almacena sin conexión: los activos de la página en una caché y los videos en una base de datos IndexedDB.

+ +

Resumen

+ +

Eso es todo por ahora. Esperamos que hayas encontrado útil nuestro resumen de las tecnologías de almacenamiento de lado del cliente.

+ +

Ve también

+ + + +

{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/client-side_web_apis/fetching_data/index.html b/files/es/learn/javascript/client-side_web_apis/fetching_data/index.html new file mode 100644 index 0000000000..ab34b8c319 --- /dev/null +++ b/files/es/learn/javascript/client-side_web_apis/fetching_data/index.html @@ -0,0 +1,373 @@ +--- +title: Fetching data from the server +slug: Learn/JavaScript/Client-side_web_APIs/Fetching_data +translation_of: Learn/JavaScript/Client-side_web_APIs/Fetching_data +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs/Third_party_APIs", "Learn/JavaScript/Client-side_web_APIs")}}
+ +

Otra tarea muy común en páginas web y en aplicaciones es tomar elementos individuales de datos desde el servidor para actualizar secciones de la página web sin tener que cargar toda una nueva página. Este aparentemente pequeño detalle tiene un gran impacto en el desempeño y comportamiento de los sitios, por eso en este artículo, explicaremos el concepto y veremos las tecnologías que hacen esto posible, como ser XHLHttpRequest y FetchAPI. 

+ + + + + + + + + + + + +
Prerequisitos:JavaScript básico (ver first steps, building blocks, JavaScript objects),  basics of Client-side APIs
Objetivo:Aprender como extraer datos desde el servidor y usarlo para cargar contenido en la página web. 
+ +

Cúal es el problema aquí?

+ +

Originalmente cargar páginas en la web era simple  — tu enviabas una solicitud de la página web al servidor, y si no había ningún problema, los servicios encargados de la página web la descargaban y mostraban en tu computadora.

+ +

A basic representation of a web site architecture

+ +

El problema con este modelo es que si tu quieres actualizar cualquier parte de la página, por ejemplo, mostrar el nuevo set de productos o cargar una nueva página, tu tenías que cargar toda la página de nuevo. Esto es extremadamente un desperdicio y resultaba ser una experiencia pobre al usuario, especialmente cuando la página es más grande y más compleja. 

+ +

Introduciendo Ajax

+ +

This led to the creation of technologies that allow web pages to request small chunks of data (such as HTML, {{glossary("XML")}}, JSON, or plain text) and display them only when needed, helping to solve the problem described above.

+ +

This is achieved by using APIs like {{domxref("XMLHttpRequest")}} or — more recently — the Fetch API. These technologies allow web pages to directly handle making HTTP requests for specific resources available on a server and formatting the resulting data as needed before it is displayed.

+ +
+

Note: In the early days, this general technique was known as Asynchronous JavaScript and XML (Ajax), because it tended to use {{domxref("XMLHttpRequest")}} to request XML data. This is normally not the case these days (you'd be more likely to use XMLHttpRequest or Fetch to request JSON), but the result is still the same, and the term "Ajax" is still often used to describe the technique.

+
+ +

A simple modern architecture for web sites

+ +

The Ajax model involves using a web API as a proxy to more intelligently request data rather than just having the browser reload the entire page. Let's think about the significance of this:

+ +
    +
  1. Go to one of your favorite information-rich sites, like Amazon, YouTube, CNN, etc., and load it.
  2. +
  3. Now search for something, like a new product. The main content will change, but most of the surrounding information, like the header, footer, navigation menu, etc., will stay the same.
  4. +
+ +

This is a really good thing because:

+ + + +

To speed things up even further, some sites also store assets and data on the user's computer when they are first requested, meaning that on subsequent visits they use the local versions instead of downloading fresh copies when the page is first loaded. The content is only reloaded from the server when it has been updated.

+ +

A basic web app data flow architecture

+ +

A basic Ajax request

+ +

Let's look at how such a request is handled, using both {{domxref("XMLHttpRequest")}} and Fetch. For these examples, we'll request data out of a few different text files and use them to populate a content area.

+ +

This series of files will act as our fake database; in a real application, we'd be more likely to use a server-side language like PHP, Python, or Node to request our data from a database. Here, however, we want to keep it simple and concentrate on the client-side part of this.

+ +

XMLHttpRequest

+ +

XMLHttpRequest (which is frequently abbreviated to XHR) is a fairly old technology now — it was invented by Microsoft in the late '90s, and has been standardized across browsers for quite a long time.

+ +
    +
  1. +

    To begin this example, make a local copy of ajax-start.html and the four text files — verse1.txt, verse2.txt, verse3.txt, and verse4.txt — in a new directory on your computer. In this example, we will load a different verse of the poem (which you may well recognize) via XHR when it's selected in the drop-down menu.

    +
  2. +
  3. +

    Just inside the {{htmlelement("script")}} element, add the following code. This stores a reference to the {{htmlelement("select")}} and {{htmlelement("pre")}} elements in variables and defines an {{domxref("GlobalEventHandlers.onchange","onchange")}} event handler function so that when the select's value is changed, its value is passed to an invoked function updateDisplay() as a parameter.

    + +
    var verseChoose = document.querySelector('select');
    +var poemDisplay = document.querySelector('pre');
    +
    +verseChoose.onchange = function() {
    +  var verse = verseChoose.value;
    +  updateDisplay(verse);
    +};
    +
  4. +
  5. +

    Let's define our updateDisplay() function. First of all, put the following beneath your previous code block — this is the empty shell of the function:

    + +
    function updateDisplay(verse) {
    +
    +};
    +
  6. +
  7. +

    We'll start our function by constructing a relative URL pointing to the text file we want to load, as we'll need it later. The value of the {{htmlelement("select")}} element at any time is the same as the text inside the selected {{htmlelement("option")}} (unless you specify a different value in a value attribute) — so for example "Verse 1". The corresponding verse text file is "verse1.txt", and is in the same directory as the HTML file, therefore just the file name will do.

    + +

    However, web servers tend to be case sensitive, and the file name doesn't have a space in it. To convert "Verse 1" to "verse1.txt" we need to convert the V to lower case, remove the space, and add .txt on the end. This can be done with {{jsxref("String.replace", "replace()")}}, {{jsxref("String.toLowerCase", "toLowerCase()")}}, and simple string concatenation. Add the following lines inside your updateDisplay() function:

    + +
    verse = verse.replace(" ", "");
    +verse = verse.toLowerCase();
    +var url = verse + '.txt';
    +
  8. +
  9. +

    To begin creating an XHR request, you need to create a new request object using the {{domxref("XMLHttpRequest.XMLHttpRequest", "XMLHttpRequest()")}} constructor. You can call this object anything you like, but we'll call it request to keep things simple. Add the following below your previous lines:

    + +
    var request = new XMLHttpRequest();
    +
  10. +
  11. +

    Next, you need to use the {{domxref("XMLHttpRequest.open","open()")}} method to specify what HTTP request method to use to request the resource from the network, and what its URL is. We'll just use the GET method here and set the URL as our url variable. Add this below your previous line:

    + +
    request.open('GET', url);
    +
  12. +
  13. +

    Next, we'll set the type of response we are expecting — which is defined by the request's {{domxref("XMLHttpRequest.responseType", "responseType")}} property — as text. This isn't strictly necessary here — XHR returns text by default — but it is a good idea to get into the habit of setting this in case you want to fetch other types of data in the future. Add this next:

    + +
    request.responseType = 'text';
    +
  14. +
  15. +

    Fetching a resource from the network is an {{glossary("asynchronous")}} operation, meaning that you have to wait for that operation to complete (e.g., the resource is returned from the network) before you can do anything with that response, otherwise, an error will be thrown. XHR allows you to handle this using its {{domxref("XMLHttpRequest.onload", "onload")}} event handler — this is run when the {{event("load")}} event fires (when the response has returned). When this has occurred, the response data will be available in the response property of the XHR request object.

    + +

    Add the following below your last addition. You'll see that inside the onload event handler we are setting the textContent of the poemDisplay (the {{htmlelement("pre")}} element) to the value of the {{domxref("XMLHttpRequest.response", "request.response")}} property.

    + +
    request.onload = function() {
    +  poemDisplay.textContent = request.response;
    +};
    +
  16. +
  17. +

    The above is all set up for the XHR request — it won't actually run until we tell it to, which is done using the {{domxref("XMLHttpRequest.send","send()")}} method. Add the following below your previous addition to complete the function:

    + +
    request.send();
    +
  18. +
  19. +

    One problem with the example as it stands is that it won't show any of the poem when it first loads. To fix this, add the following two lines at the bottom of your code (just above the closing </script> tag) to load verse 1 by default, and make sure the {{htmlelement("select")}} element always shows the correct value:

    + +
    updateDisplay('Verse 1');
    +verseChoose.value = 'Verse 1';
    +
  20. +
+ +

Serving your example from a server

+ +

Some browsers (including Chrome) will not run XHR requests if you just run the example from a local file. This is because of security restrictions (for more on web security, read Website security).

+ +

To get around this, we need to test the example by running it through a local web server. To find out how to do this, read How do you set up a local testing server?

+ +

Fetch

+ +

The Fetch API is basically a modern replacement for XHR; it was introduced in browsers recently to make asynchronous HTTP requests easier to do in JavaScript, both for developers and other APIs that build on top of Fetch.

+ +

Let's convert the last example to use Fetch instead.

+ +
    +
  1. +

    Make a copy of your previous finished example directory. (If you didn't work through the previous exercise, create a new directory and inside it make copies of xhr-basic.html and the four text files — verse1.txt, verse2.txt, verse3.txt, and verse4.txt.)

    +
  2. +
  3. +

    Inside the updateDisplay() function, find the XHR code:

    + +
    var request = new XMLHttpRequest();
    +request.open('GET', url);
    +request.responseType = 'text';
    +
    +request.onload = function() {
    +  poemDisplay.textContent = request.response;
    +};
    +
    +request.send();
    +
  4. +
  5. +

    Replace all the XHR code with this:

    + +
    fetch(url).then(function(response) {
    +  response.text().then(function(text) {
    +    poemDisplay.textContent = text;
    +  });
    +});
    +
  6. +
  7. +

    Load the example in your browser (running it through a web server) and it should work just the same as the XHR version, provided you are running a modern browser.

    +
  8. +
+ +

So what is going on in the Fetch code?

+ +

First of all, we invoke the {{domxref("WorkerOrWindowGlobalScope.fetch()","fetch()")}} method, passing it the URL of the resource we want to fetch. This is the modern equivalent of {{domxref("XMLHttpRequest.open","request.open()")}} in XHR, plus you don't need any equivalent to .send().

+ +

After that, you can see the {{jsxref("Promise.then",".then()")}} method chained onto the end of fetch() — this method is a part of {{jsxref("Promise","Promises")}}, a modern JavaScript feature for performing asynchronous operations. fetch() returns a promise, which resolves to the response sent back from the server — we use .then() to run some follow-up code after the promise resolves, which is the function we've defined inside it. This is the equivalent of the onload event handler in the XHR version.

+ +

This function is automatically given the response from the server as a parameter when the fetch() promise resolves. Inside the function we grab the response and run its {{domxref("Body.text","text()")}} method, which basically returns the response as raw text. This is the equivalent of request.responseType = 'text' in the XHR version.

+ +

You'll see that text() also returns a promise, so we chain another .then() onto it, inside of which we define a function to receive the raw text that the text() promise resolves to.

+ +

Inside the inner promise's function, we do much the same as we did in the XHR version — set the {{htmlelement("pre")}} element's text content to the text value.

+ +

Aside on promises

+ +

Promises are a bit confusing the first time you meet them, but don't worry too much about this for now. You'll get used to them after a while, especially as you learn more about modern JavaScript APIs — most of the newer ones are heavily based on promises.

+ +

Let's look at the promise structure from above again to see if we can make some more sense of it:

+ +
fetch(url).then(function(response) {
+  response.text().then(function(text) {
+    poemDisplay.textContent = text;
+  });
+});
+ +

The first line is saying "fetch the resource located at URL" (fetch(url)) and "then run the specified function when the promise resolves" (.then(function() { ... })). "Resolve" means "finish performing the specified operation at some point in the future". The specified operation, in this case, is to fetch a resource from a specified URL (using an HTTP request), and return the response for us to do something with.

+ +

Effectively, the function passed into then() is a chunk of code that won't run immediately. Instead, it will run at some point in the future when the response has been returned. Note that you could also choose to store your promise in a variable and chain {{jsxref("Promise.then",".then()")}} onto that instead. The code below would do the same thing:

+ +
var myFetch = fetch(url);
+
+myFetch.then(function(response) {
+  response.text().then(function(text) {
+    poemDisplay.textContent = text;
+  });
+});
+ +

Because the fetch() method returns a promise that resolves to the HTTP response, any function you define inside a .then() chained onto the end of it will automatically be given the response as a parameter. You can call the parameter anything you like — the below example would still work:

+ +
fetch(url).then(function(dogBiscuits) {
+  dogBiscuits.text().then(function(text) {
+    poemDisplay.textContent = text;
+  });
+});
+ +

But it makes more sense to call the parameter something that describes its contents.

+ +

Now let's focus just on the function:

+ +
function(response) {
+  response.text().then(function(text) {
+    poemDisplay.textContent = text;
+  });
+}
+ +

The response object has a method {{domxref("Body.text","text()")}} that takes the raw data contained in the response body and turns it into plain text — the format we want it in. It also returns a promise (which resolves to the resulting text string), so here we use another {{jsxref("Promise.then",".then()")}}, inside of which we define another function that dictates what we want to do with that text string. We are just setting the textContent property of our poem's {{htmlelement("pre")}} element to equal the text string, so this works out pretty simple.

+ +

It is also worth noting that you can directly chain multiple promise blocks (.then() blocks, but there are other types too) onto the end of one another, passing the result of each block to the next block as you travel down the chain. This makes promises very powerful.

+ +

The following block does the same thing as our original example, but is written in a different style:

+ +
fetch(url).then(function(response) {
+  return response.text()
+}).then(function(text) {
+  poemDisplay.textContent = text;
+});
+ +

Many developers like this style better, as it is flatter and arguably easier to read for longer promise chains — each subsequent promise comes after the previous one, rather than being inside the previous one (which can get unwieldy). The only other difference is that we've had to include a return statement in front of response.text(), to get it to pass its result on to the next link in the chain.

+ +

Which mechanism should you use?

+ +

This really depends on what project you are working on. XHR has been around for a long time now and has very good cross-browser support. Fetch and Promises, on the other hand, are a more recent addition to the web platform, although they're supported well across the browser landscape, with the exception of Internet Explorer.

+ +

If you need to support older browsers, then an XHR solution might be preferable. If however you are working on a more progressive project and aren't as worried about older browsers, then Fetch could be a good choice.

+ +

You should really learn both — Fetch will become more popular as Internet Explorer declines in usage (IE is no longer being developed, in favor of Microsoft's new Edge browser), but you might need XHR for a while yet.

+ +

A more complex example

+ +

To round off the article, we'll look at a slightly more complex example that shows some more interesting uses of Fetch. We have created a sample site called The Can Store — it's a fictional supermarket that only sells canned goods. You can find this example live on GitHub, and see the source code.

+ +

A fake ecommerce site showing search options in the left hand column, and product search results in the right hand column.

+ +

By default, the site displays all the products, but you can use the form controls in the left hand column to filter them by category, or search term, or both.

+ +

There is quite a lot of complex code that deals with filtering the products by category and search terms, manipulating strings so the data displays correctly in the UI, etc. We won't discuss all of it in the article, but you can find extensive comments in the code (see can-script.js).

+ +

We will however explain the Fetch code.

+ +

The first block that uses Fetch can be found at the start of the JavaScript:

+ +
fetch('products.json').then(function(response) {
+  return response.json();
+}).then(function(json) {
+  products = json;
+  initialize();
+}).catch(function(err) {
+  console.log('Fetch problem: ' + err.message);
+});
+ +

The fetch() function returns a promise. If this completes successfully, the function inside the first .then() block contains the response returned from the network.

+ +

Inside this function we run {{domxref("Body.json","json()")}} on the response, not {{domxref("Body.text","text()")}}, as we want to return our response as structured JSON data, not plain text.

+ +

Next, we chain another .then() onto the end of our first one, the success function that contains the json returned from the response.json() promise. We set this to be the value of the products global object, then run initialize(), which starts the process of displaying all the products in the user interface.

+ +

To handle errors, we chain a .catch() block onto the end of the chain. This runs if the promise fails for some reason. Inside it, we include a function that is passed as a parameter, an error object. This error object can be used to report the nature of the error that has occurred, in this case we do it with a simple console.log().

+ +

However, a complete website would handle this error more gracefully by displaying a message on the user's screen and perhaps offering options to remedy the situation, but we don't need anything more than a simple console.log().

+ +

You can test the fail case yourself:

+ +
    +
  1. Make a local copy of the example files (download and unpack the can-store ZIP file).
  2. +
  3. Run the code through a web server (as described above, in {{anch("Serving your example from a server")}}).
  4. +
  5. Modify the path to the file being fetched, to something like 'produc.json' (make sure it is misspelled).
  6. +
  7. Now load the index file in your browser (via localhost:8000) and look in your browser developer console. You'll see a message similar to "Network request for products.json failed with response 404: File not found".
  8. +
+ +

The second Fetch block can be found inside the fetchBlob() function:

+ +
fetch(url).then(function(response) {
+    return response.blob();
+}).then(function(blob) {
+  // Convert the blob to an object URL — this is basically an temporary internal URL
+  // that points to an object stored inside the browser
+  var objectURL = URL.createObjectURL(blob);
+  // invoke showProduct
+  showProduct(objectURL, product);
+});
+ +

This works in much the same way as the previous one, except that instead of using {{domxref("Body.json","json()")}}, we use {{domxref("Body.blob","blob()")}}. In this case we want to return our response as an image file, and the data format we use for that is Blob (the term is an abbreviation of "Binary Large Object" and can basically be used to represent large file-like objects, such as images or video files).

+ +

Once we've successfully received our blob, we create an object URL out of it using {{domxref("URL.createObjectURL()", "createObjectURL()")}}. This returns a temporary internal URL that points to an object referenced inside the browser. These are not very readable, but you can see what one looks like by opening up the Can Store app, Ctrl-/Right-clicking on an image, and selecting the "View image" option (which might vary slightly depending on what browser you are using). The object URL will be visible inside the address bar, and should be something like this:

+ +
blob:http://localhost:7800/9b75250e-5279-e249-884f-d03eb1fd84f4
+ +

Challenge: An XHR version of the Can Store

+ +

We'd like you to try converting the Fetch version of the app to use XHR as a useful bit of practice. Take a copy of the ZIP file, and try modifying the JavaScript as appropriate.

+ +

Some helpful hints:

+ + + +
+

Note: If you have trouble with this, feel free to check your code against the finished version on GitHub (see the source here, and also see it running live).

+
+ +

Summary

+ +

This article shows how to start working with both XHR and Fetch to fetch data from the server.

+ +

See also

+ +

There are however a lot of different subjects discussed in this article, which has only really scratched the surface. For a lot more detail on these subjects, try the following articles:

+ + + +
{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs/Third_party_APIs", "Learn/JavaScript/Client-side_web_APIs")}}
+ +
+

In this module

+ + +
diff --git a/files/es/learn/javascript/client-side_web_apis/index.html b/files/es/learn/javascript/client-side_web_apis/index.html new file mode 100644 index 0000000000..731edea2a3 --- /dev/null +++ b/files/es/learn/javascript/client-side_web_apis/index.html @@ -0,0 +1,53 @@ +--- +title: Client-side web APIs +slug: Learn/JavaScript/Client-side_web_APIs +tags: + - API + - Articles + - Beginner + - CodingScripting + - DOM + - Graphics + - JavaScript + - Landing + - Learn + - Media + - Module + - NeedsTranslation + - TopicStub + - WebAPI + - data +translation_of: Learn/JavaScript/Client-side_web_APIs +--- +
{{LearnSidebar}}
+ +

Cuando se escribe JavaScript para sitios web o aplicaciones del lado del cliente, no pasará mucho tiempo antes de que comience a usar APIs ("Application Programming Interfaces"). Estas son interfaces para manipular diferentes aspectos del navegador y el sistema operativo sobre el cuál se esta ejecutando, o incluso datos de otros sitios web o servicios. En este módulo, vamos a aprender que son las APIs  y cómo utilizar algunas de las API más comunes que encuentran al momento de desarrollar. 

+ +

Requisitos

+ +

Para aprovechar al máximo este módulo, debería haber trabajado con los módulos anteriores de JavaScript (Primeros Pasos, Bloques de construcción, y Objetos en JavaScript). De todos modos, esos módulos involucran el uso de varias APIs simples, ya que es dificil escribir ejemplos en Javascript del lado del cliente sin dar uso de ellos! Para este tutorial, asumiremos que se tiene conocimiento basico sobre JavaScript  y exploraremos las API web mas comunes con un poco más de detalle.

+ +

Conocimiento basico de HTML y CSS tambien seria util.

+ +
+

Nota: Si está trabajando en un dispositivo en el que no tiene la capacidad de crear sus propios archivos, puede probar (la mayoría de) los ejemplos de código en un programa de codificación en línea como JSBinThimble.

+
+ +

Guías

+ +
+
Introducción a web APIs
+
En primer lugar, comenzaremos observando las API de alto nivel: ¿qué son, cómo funcionan, cómo las utilizan en su código y cómo están estructuradas? También veremos cuáles son las diferentes principales clases de APIs y qué tipo de usos tienen.
+
Manipulacion de documentos
+
Al escribir páginas web y aplicaciones, una de las cosas más comunes que querrás hacer es manipular los documentos web de alguna manera. Esto generalmente se hace usando el Document Object Model (DOM), un conjunto de APIs para controlar el HTML y la información de sus estilos que hace un uso intensivo del objeto  {{domxref("Document")}} . En este artículo, veremos cómo usar el DOM en detalle, junto con algunas otras API que pueden alterar su entorno de maneras interesantes.
+
Obteniendo data desde el servidor
+
Otra tarea frecuente en las en las aplicaciones y los sitios web modernos, es recuperar los datos individuales de un elemento del seridor para actualizar solo una seccion de la pagina sin tener que cargar una pagina web completamente nueva. Este detalle, aparentemente pequeño, ha tenido un gran impacto en el rendimiento y el comportamiento de los sitios, En este artículo, explicaremos el concepto y veremos las tecnologías que hacen esto posible, como {{domxref("XMLHttpRequest")}} y el Fetch API.
+
APIs de terceros
+
Las APIs que hemos cubierto hasta ahora están integradas en el navegador, pero no todas las APIs lo estan. Muchos grandes sitios web y servicios tales como Google Maps, Twitter, Facebook, PayPal, etc. proporcionan APIs que permiten a los desarrolladores hacer uso de sus datos (p.ej. mostrando tu actividad en twitter dentro de tu blog) o sus servicios (p.ej. mostrar una ubicacion personalizada porGoogle Maps en tu sitio, o usar el inicio de sesión de Facebook para que inicien sesión tus usuarios). Este artículo analiza la diferencia entre las API del navegador y las API de terceros y muestra algunos usos típicos de este último.
+
Dibujar gráficos
+
El navegador contiene algunas herramientas de programación poderosas para gráficos, desde el lenguaje de Gráficos de Vectores Escalables (SVG), hasta APIs para dibujar elementos HTML {{htmlelement("canvas")}}, (ver El API Canvas y WebGL). Este articulo provee una introducción al Canvas API, y además recursos que te van a permirir aprender más.
+
APIs de audio y video
+
HTML5 for embedding rich media in documents — {{htmlelement("video")}} and {{htmlelement("audio")}} — which in turn come with their own APIs for controlling playback, seeking, etc. This article shows you how to do common tasks such as creating custom playback controls.
+
Almacenamiento del lado del Cliente
+
Modernos navegadores web implementan un número de diferente de tecnologías que te permiten almacenar datos relacionados a sitios y recuperarlos cuando sea necesario permitiendote almacenarlos por mucho tiempo, almacenar sitios fuera de linea, y más. Este articulo explica aspectos los principios de como trabaja.
+
diff --git "a/files/es/learn/javascript/client-side_web_apis/introducci\303\263n/index.html" "b/files/es/learn/javascript/client-side_web_apis/introducci\303\263n/index.html" new file mode 100644 index 0000000000..fc73d4ebc9 --- /dev/null +++ "b/files/es/learn/javascript/client-side_web_apis/introducci\303\263n/index.html" @@ -0,0 +1,274 @@ +--- +title: Introducción a las APIs web +slug: Learn/JavaScript/Client-side_web_APIs/Introducción +translation_of: Learn/JavaScript/Client-side_web_APIs/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}
+ +

En primer lugar empezaremos echando un vistazo a las APIS desde un nivel superior — ¿qué son, cómo funcionan, cómo usarlas en el código, y cómo están estructuradas?. También echaremos un vistazo a cuáles son los principales tipos de APIs, y para qué se usan.

+ + + + + + + + + + + + +
Pre requisitos:Conocimientos básicos de informática, principios básicos de HTML, CSS y JavaScript (ver primeros pasos, bloques de construcción, objetos JavaScript).
Objetivo:Familiarizarse con las APIs, saber qué pueden hacer y cómo usarlas en tu código.
+ +

¿Qué son las APIs?

+ +

Las Interfaces de Programacion de Aplicaciones (APIs por sus siglas en inglés) son construcciones disponibles en los lenguajes de programación que permiten a los desarrolladores crear funcionalidades complejas de una manera simple. Estas abstraen el código más complejo para proveer una sintaxis más fácil de usar en su lugar.

+ +

Como ejemplo, piensa en el suministro de electricidad de tu casa, apartamento, o cualquier otro edificio. Si quieres usar un electrodoméstico, simplemente lo conectas en un enchufe y funciona. No intentas conectarlo directamente a la fuente de alimentación — hacerlo sería muy ineficiente y, si no eres electricista, dificil y peligroso.

+ +

+ +

Fuente de la imagen: Overloaded plug socket por The Clear Communication People, en Flickr.

+ +

De la misma manera, si quisieras programar gráficos 3D, sería mucho más facil hacerlo usando una API escrita en un lenguaje de alto nivel como JavaScript o Python, en lugar de intentar escribir código de bajo nivel (por ejemplo: C o C++) que controle directamente la GPU del equipo u otras funciones gráficas.

+ +
+

Nota: Consulta también la entrada API en el glosario para una descripción más detallada.

+
+ +

APIs en JavaScript del lado cliente

+ +

JavaScript del lado cliente, particularmente, tiene muchas APIs disponibles — estas no son parte del lenguaje en sí, sino que están construidas sobre el núcleo de este lenguaje de programación, proporcionándote superpoderes adicionales para usar en tu código. Por lo general, se dividen en dos categorías:

+ + + +

+ +

Relacion entre JavaScript, APIs, y otras herramientas de JavaScript

+ +

Anteriormente hablamos sobre qué son las APIs de JavaScript del lado cliente y cómo se relacionan con este lenguaje. Recapitulemos ahora para dejarlo claro, y veamos también dónde encajan otras herramientas de JavaScript:

+ + + +

¿Qué pueden hacer las APIs?

+ +

Hay una gran cantidad de APIs disponibles en los navegadores modernos que te permiten hacer una gran variedad de cosas en tu código. Puedes verlo echando un vistazo al índice de APIs de MDN.

+ +

APIs de navegador más comunes

+ +

En particular, las categorías más comunes de APIs de navegador más usadas (y que trataremos con mayor detalle en este módulo) son:

+ + + +

APIs populares de terceros

+ +

Existe una gran variedad de APIs de terceros, algunas de las más populares de las que querrás hacer uso en algún momento son:

+ + + +
+

Nota: puedes encontrar información de una gran cantidad de APIs de terceros en el Programmable Web API directory.

+
+ +

¿Cómo funcionan las APIs?

+ +

Las distintas APIs de JavaScript funcionan de forma ligeramente diferente, pero generalmente tienen características similares y una forma parecida en cómo trabajan.

+ +

Están basadas en objetos

+ +

Las APIs interactúan con tu código usando uno o más Objetos JavaScript, que sirven como contenedores para los datos que usa la API (contenidos en las propiedades del objeto), y la funcionalidad que la API provee (contenida en los métodos del objeto).

+ +
+

Nota: si no estás familiarizado en cómo trabajar con objetos, deberías volver atrás y revisar el módulo de objetos JavaScript antes de seguir.

+
+ +

Volvamos al ejemplo de la API de Geolocalización, que es una API muy simple que consiste en unos pocos objetos sencillos:

+ + + +

¿Cómo interactúan estos objetos? Si miras a nuestro ejemplo maps-example.html (ver también en vivo), encontrarás el siguiente código:

+ +
navigator.geolocation.getCurrentPosition(function(position) {
+  var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+  var myOptions = {
+    zoom: 8,
+    center: latlng,
+    mapTypeId: google.maps.MapTypeId.TERRAIN,
+    disableDefaultUI: true
+  }
+  var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions);
+});
+ +
+

Nota: cuando cargues por primera vez el ejemplo de arriba, se te mostrará un mensaje preguntando si deseas compartir tu localización con esta aplicación (ver la sección {{anch("They have additional security mechanisms where appropriate")}} que se encuentra más adelante en este artículo). Deberás estar de acuerdo con esto para poder ver tu localización en el mapa. Si aún así sigues sin ver tu localización, tal vez debas establecer los permisos manualmente; lo puedes hacer de varias formas dependiendo del navegador que estés usando; por ejemplo en Firefox debes ir a  > Tools > Page Info > Permissions, y cambiar la configuración para Share Location; en Chrome ve a Settings > Privacy > Show advanced settings > Content settings y cambia las opciones para Location.

+
+ +

Primero queremos usar el método {{domxref("Geolocation.getCurrentPosition()")}} para retornar la posición actuali de nuestro dispositivo. El objeto {{domxref("Geolocation")}} del navegador es accedido llamando a la propiedad {{domxref("Navigator.geolocation")}}, así que comenzaremos haciendo:

+ +
navigator.geolocation.getCurrentPosition(function(position) { ... });
+ +

Lo que es equivalente a hacer algo como:

+ +
var myGeo = navigator.geolocation;
+myGeo.getCurrentPosition(function(position) { ... });
+ +

Pero podemos usar la sintaxis con punto para concatener nuestros accesos a propiedades/métodos reduciendo el número de líneas que tenemos que escribir.

+ +

El método {{domxref("Geolocation.getCurrentPosition()")}} solamente tiene un parámetroobligatorio, que es una función anónima que se ejecutará cuando se recupere correctamente la ubicación del dispositivo. Esta función tiene un parámetro, que contiene un objeto {{domxref("Position")}} con la representación de los datos de la posición actual.

+ +
+

Nota: una función que es tomada por otra función como argumento es conocida con el nombre de callback function.

+
+ +

Este patrón de invocar una función solamente cuando una operación ha sido completada es muy común en las APIs de Javascript — asegurando que una operación ha sido completada antes de intentar usar los datos que retorna en otra operación. Estas operaciones se llaman operaciones asíncronas. Puesto que obtener la posición actual del dispositivo recae en un componente externo (el GPS del dispositivo u otro hardware de geolocalización), no podemos asegurar que se haga a tiempo para usar inmediatamente los datos. Por tanto, algo así no funcionará:

+ +
var position = navigator.geolocation.getCurrentPosition();
+var myLatitude = position.coords.latitude;
+ +

Si la primera línea no ha retornado todavía su resultado, la segunda línea lanzará un error puesto que los datos de posición no estarán disponibles. Por esa razón, las APIs que tienen operaciones asíncronas se diseñan para usar {{glossary("callback function")}}s, o el sistema más moderno de Promises, que se ha introducido en ECMAScript 6 y se está usando mucho en las APIs más nuevas.

+ +

Vamos a combinar la API de geolocalización con una API de terceros — la API de Google Maps — que se usa para dibujar la localización retornada por getCurrentPosition() en un mapa de Google. Haremos disponible esta API en nuestra página vinculándonos a ella — encontrarás esta línea en el HTML:

+ +
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA"></script>
+ +

Para usar la API, primero creamos una instancia del objeto LatLng usando el constructor google.maps.LatLng(), que toma los valores de nuestra {{domxref("Coordinates.latitude")}} y {{domxref("Coordinates.longitude")}} geolocalizada como parámetros:

+ +
var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+ +

Este objeto quedará establecido como el valor de la propiedad center de un objeto de opciones que hemos llamado myOptions. Entonces crearemos una instancia de objeto para representar nuestro mapa llamando al constructor de google.maps.Map(), pasándole sus dos parámetros — una referencia al elemento {{htmlelement("div")}} donde queremos presentar el mapa (con ID map_canvas), y el objeto de opciones que acabamos de definir.

+ +
var myOptions = {
+  zoom: 8,
+  center: latlng,
+  mapTypeId: google.maps.MapTypeId.TERRAIN,
+  disableDefaultUI: true
+}
+
+var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions);
+ +

Una vez hecho, veremos dibujado nuestro mapa.

+ +

Este último bloque de código muestra dos patrones habituales que veremos en muchas APIs. Primero, los objetos de las APIs habitualmente disponen de constructores, que son invocados para crear instancias de esos objetos que que habitualmente usaremos en nuestros programas. Segundo, los objetos de las APIs a menudo ofrecen múltiples opciones que pueden ser adaptadas para obtener exactamente lo que queremos en nuestro programa. Los constructores de las APIs habitualmente aceptan un objeto de opciones como parámetro, que es donde se deben establecer dichas opciones.

+ +
+

Nota: no te preocupes si no entiendes todos los detalles de este ejemplo inmediantamente. Los repasaremos usando APIs de terceros con más detalle en un artículo futuro.

+
+ +

Tienen puntos de acceso reconocibles

+ +

Cuando uses una API, debes estar seguro que conoces dónde están los puntos de acceso para ella. En la API de Geolocalización esto es bastante sencillo  — es la propiedad {{domxref("Navigator.geolocation")}}, que retorna el objeto del navegador {{domxref("Geolocation")}} que contiene todos los métodos útiles de geolocalización disponibles en su interior.

+ +

La API del Modelo de Objetos del Navegador (DOM) tiene un punto de acceso todavía más simple — sus características las podemos encontrar colgando del objeto {{domxref("Document")}}, o una instancia de un elemento HTML que queremos modificar de alguna forma, por ejemplo:

+ +
var em = document.createElement('em'); // crear un nuevo elemento em
+var para = document.querySelector('p'); // referencia a un elemento p existente
+em.textContent = 'Hello there!'; // dar al em algo de contenido textual
+para.appendChild(em); // ubicar el em dentro del párrafo
+ +

Otras APIs tienen puntos de acceso ligeramente más complejos, que a menudo implican crear un contexto específico para escribir el código de la API. Por ejemplo, el objeto de contexto de la API Canvas se crea obteniendo una referencia al elemento {{htmlelement("canvas")}} en el que quieres dibujar, y a continuación invocando su método {{domxref("HTMLCanvasElement.getContext()")}}:

+ +
var canvas = document.querySelector('canvas');
+var ctx = canvas.getContext('2d');
+ +

Cualquier cosa que queramos hacerle al canvas, se conseguirá llamando a las propiedades y métodos del objeto de contexto (que es una instancia de {{domxref("CanvasRenderingContext2D")}}), por ejemplo:

+ +
Ball.prototype.draw = function() {
+  ctx.beginPath();
+  ctx.fillStyle = this.color;
+  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+  ctx.fill();
+};
+ +
+

Nota: puedes ver este código en acción en nuetro bouncing balls demo (y también verlo funcionando).

+
+ +

Usan eventos para manejar cambios en su estado

+ +

Ya hemos discutido anteriormente los eventos en este curso, en nuestro artículo de Introducción a los eventos — este artículo detalla qué son los eventos del lado del cliente y cómo se usan en el código. Si no estás familiarizado en cómo se trabaja con la API de eventos del lado del cliente, deberías ir a consultar este artículo antes de continuar.

+ +

Algunas APIs web no contienen eventos, pero algunas otras sí contienen un buen número de ellos. Las propiedades para manejarlos, que nos permiten ejecutar funciones cuando los eventos se producen, generalmente se listan en nuestro material de referencia en secciones de "Manejadores de Eventos" separadas. Como ejemplo simple, instancias del objeto XMLHttpRequest (cada uno representa una petición HTTP al servidor para recuperar un nuevo recurso de algún tipo) tienen un número de eventos disponibles, por ejemplo el evento load que es disparado cuando una respuesta ha sido retornada satisfactoriamente conteniendo el recurso solicitado, y ahora está disponible.

+ +

El siguiente código aporta un ejemplo simple de cómo se debe usar esto:

+ + + +
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
+var request = new XMLHttpRequest();
+request.open('GET', requestURL);
+request.responseType = 'json';
+request.send();
+
+request.onload = function() {
+  var superHeroes = request.response;
+  populateHeader(superHeroes);
+  showHeroes(superHeroes);
+}
+ +
+

Nota: puedes ver este código en acción en nuestro ejemplo ajax.html (verlo en vivo).

+
+ +

Las primeras cinco líneas especifican la licalización del recurso que queremos recuperar, se crea una nueva instancia del objeto con la petición usando el constructor XMLHttpRequest(), se abre una petición HTTP GET para recuperar el recurso especificado, se indica que la respuesta debería ser enviada en formato JSON, y finalmente se envía la petición.

+ +

El manejador onload especifica entonces qué hacer con la respuesta. Ya sabemos que la respuesta será retornada satisfactoriamente y estará disponible tras producirse el evento load (a menos que haya sucedido un error), así que salvamos la respuesta que contiene el código JSON retornado en la variable superHeroes, luego lo pasamos a dos funciones diferentes para un procesado posterior.

+ +

Tienen mecanismos adicionales de seguridad donde sea necesario

+ +

Las características de las WebAPI están sujetas a las mismas consideraciones de seguridad que JavaScript y otras tecnologías web (por ejemplo same-origin policy), pero a veces tienen mecanismos adicionales de seguridad. Por ejemplo, algunas de las WebAPIs más modernas solamente funcionan en páginas servidas mediante HTTPS debido a que transmiten información potencialmente sensible (algunos ejemplos son Service Workers y Push).

+ +

Además, algunas WebAPIs solicitarán permiso al usuario para ser activadas cuando se produzcan las llamadas desde el código. Como ejemplo, habrás observado un cuadro de diálogo como éste al probar nuestro ejemplo anterior de Geolocalización:

+ +

+ +

La Notifications API solicita los permisos de una forma parecida:

+ +

+ +

Estos diálogos solicitando permiso se muestran al usuario por motivos de seguridad — si no estuvieran, los sitios podrían rastrear la localización sin que el usuario lo supiera o bombardearlo con un montón de notificaciones molestas.

+ +

Resumen

+ +

En este punto, deberías tener ya una buena idea de los que son las APIs, cómo trabajan y qué puedes hacer con ellas en tu código JavaScript. Seguramente estarás con ganas de comenzar a hacer cosas divertidas con algunas APIs específicas, así que ¡vamos allá! A continuación veremos cómo manipular documentos con el Modelo de Objetos del Documento (DOM).

+ +

{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/a_first_splash/index.html b/files/es/learn/javascript/first_steps/a_first_splash/index.html new file mode 100644 index 0000000000..1d2f5e2be0 --- /dev/null +++ b/files/es/learn/javascript/first_steps/a_first_splash/index.html @@ -0,0 +1,613 @@ +--- +title: Un primer acercamiento a JavaScript +slug: Learn/JavaScript/First_steps/A_first_splash +tags: + - Aprender + - Artículo + - CodingScripting + - Condicionales + - Funciones + - JavaScript + - Novato + - Objetos + - Operadores + - Variables + - eventos + - 'l10n:priority' +translation_of: Learn/JavaScript/First_steps/A_first_splash +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}
+ +

Ahora que has aprendido algo sobre la teoría de JavaScript y lo que puedes hacer con ella, te daremos un curso intensivo sobre las características básicas de JavaScript a través de un tutorial completamente práctico. Aquí crearás un sencillo juego de "Adivina el número", paso a paso.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, comprensión básica de HTML y CSS, comprensión de lo que es JavaScript.
Objetivo:Tener un poco de experiencia escribiendo algo de JavaScript, y conseguir al menos una comprensión básica de lo que implica escribir un programa JavaScript.
+ +

No esperes entender todo el código inmediatamente — por ahora sólo queremos presentarte los conceptos de alto nivel, y darte una idea de como funciona JavaScript (y otros lenguajes de programación). ¡Más adelante vas a volver a ver estas características con mucho más detalle!

+ +
+

Nota: Muchas de las características que vas a ver en JavaScript son las mismas que en otros lenguajes de programación — funciones, bucles, etc. La sintaxis del código es diferente, pero los conceptos siguen siendo básicamente los mismos. La sintaxis del código es diferente, pero los conceptos siguen siendo básicamente los mismos.

+
+ +

Pensando como un  programador

+ +

Una de las cosas más difíciles de aprender en programación no es la sintaxis que necesita aprender, sino cómo aplicarla para resolver problemas del mundo real. Debes comenzar a pensar como un programador — esto generalmente implica mirar descripciones de lo que necesita hacer tu programa, determinar qué características de código necesitas para alcanzar esas cosas y cómo hacer que funcionen juntas.

+ +

Esto implica una combinación de trabajo duro, experiencia con la sintaxis de programación y práctica — más un poquito de creatividad. Mientras más programes, más habilidoso serás haciéndolo. No te podemos prometer que vas a desarrollar un "cerebro de programador" en cinco minutos, pero, a lo largo de este curso, te vamos a dar muchas oportunidades de practicar el pensar como un programador.

+ +

Teniendo esto en mente, veamos el ejemplo que vamos a construir en este artículo, y revisemos el proceso general de seccionarlo y dividirlo en tareas tangibles.

+ +

Ejemplo — Juego adivina el número

+ +

En este artículo vamos a mostrarte cómo construir el juego que puedes ver abajo:

+ + + +

{{ EmbedLiveSample('Top_hidden_code', '100%', 320, "", "", "hide-codepen-jsfiddle") }}

+ +

Juega un poco — familiarízate con el juego antes de continuar.

+ +

Imaginemos que tu jefe te ha dado el siguiente resumen para crear este juego:

+ +
+

Quiero que crees un sencillo juego del tipo "adivina el número". Se debe elegir un número aleatorio entre 1 y 100, luego desafiar al jugador a adivinar el número en 10 intentos. Después de cada intento, debería decirle al jugador si ha acertado o no — y si está equivocado, debería decirle si se ha quedado corto o se ha pasado. También debería decir los números que ya se probaron anteriormente. El juego terminará una vez que el jugador acierte o cuando se acaben los intentos. Cuando el juego termina, se le debe dar al jugador la opción de volver a jugar.

+
+ +

Al observar este resumen, lo primero que podemos hacer es comenzar a desglosar el proyecto en tareas simples y realizables, con la mayor mentalidad de programador posible:

+ +
    +
  1. Generar un número aleatorio entre 1 y 100.
  2. +
  3. Registrar el número del intento en el que el jugador se encuentre. Empezando en 1.
  4. +
  5. Darle al jugador una forma de adivinar cuál es el número.
  6. +
  7. Una vez que se ha introducido en número, registrarlo en alguna parte para que el jugador pueda ver sus intentos previos.
  8. +
  9. A continuación, comprobar si el número es correcto.
  10. +
  11. Si es correcto: +
      +
    1. Mostrar un mensaje de felicitaciones.
    2. +
    3. Hacer que el jugador no pueda introducir más intentos (esto arruinaría el juego).
    4. +
    5. Mostrar un control que permita al jugador volver a empezar el juego.
    6. +
    +
  12. +
  13. Si es incorrecto y al jugador todavía le quedan intentos: +
      +
    1. Decirle al jugador que ha fallado.
    2. +
    3. Dejar que el jugador lo intente de nuevo.
    4. +
    5. Incrementa el número de intentos en 1.
    6. +
    +
  14. +
  15. Si el jugador falla y no le quedan turnos: +
      +
    1. Decirle al jugador que el juego se ha terminado.
    2. +
    3. Hacer que el jugador no pueda introducir más intentos (esto arruinaría el juego).
    4. +
    5. Mostrar un control que permita al jugador volver a empezar el juego.
    6. +
    +
  16. +
  17. Una vez que el juego se reinicia, asegúrate de que la lógica del juego y la IU (interfaz de usuario) se restablezcan por completo, luego vuelve al paso 1.
  18. +
+ +

Veamos cómo podemos trasformar estos pasos en código, construyendo el ejemplo y explorando las características de JavaScript a medida que avanzamos.

+ +

Configuración inicial

+ +

Para empezar este tutorial, quisiéramos que hicieras una copia local del archivo number-guess-guess-game-start.html (en vivo aquí). Ábrelo en tu editor de texto y en tu navegador web. De momento, puedes ver un sencillo encabezado, un párrafo de instrucciones y un espacio para introducir un intento de número, pero no hará nada por ahora.

+ +

El lugar donde agregaremos todo nuestro código es dentro del elemento {{htmlelement("script")}} en la parte inferior del HTML:

+ +
<script>
+
+  // Tu JavaScript va aquí
+
+</script>
+
+ +

Añadiendo variables para guardar los datos

+ +

Empecemos. En primer lugar, agrega las siguientes líneas dentro de tu elemento {{htmlelement("script")}}:

+ +
let randomNumber = Math.floor(Math.random() * 100) + 1;
+
+const guesses = document.querySelector('.guesses');
+const lastResult = document.querySelector('.lastResult');
+const lowOrHi = document.querySelector('.lowOrHi');
+
+const guessSubmit = document.querySelector('.guessSubmit');
+const guessField = document.querySelector('.guessField');
+
+let guessCount = 1;
+let resetButton;
+ +

Esta sección del código establece las variables y constantes que necesitamos para almacenar los datos que nuestro programa utilizará. Las variables básicamente son contenedores de valores (como números o cadenas de texto). Creas una variable con la palabra clave let (o var) seguida de un nombre para tu variable (leerás más sobre la diferencia entre las palabras clave en el siguiente artículo). Las constantes se utilizan para almacenar valores que no deseas modificar y se crean con la palabra clave const. En este caso, estamos usando constantes para almacenar referencias a partes de nuestra interfaz de usuario; el texto dentro de algunas de ellas puede cambiar, pero los elementos HTML a los que se hace referencia permanecer iguales.

+ +

Puedes asignar un valor a tu variable o constante con un signo igual (=) seguido del valor que deseas darle.

+ +

En nuestro ejemplo:

+ + + +
+

Nota: Aprenderás mucho más sobre las variables/constantes más adelante en el curso, comenzando con el artículo siguiente.

+
+ +

Funciones

+ +

A continuación, agrega lo siguiente debajo de tu código JavaScript anterior:

+ +
function checkGuess() {
+  alert('Soy un marcador de posición');
+}
+ +

Las funciones son bloques de código reutilizable que puedes escribir una vez y ejecutar una y otra vez, ahorrando la necesidad de repetir el código todo el tiempo. Son realmente útiles. Hay varias maneras de definir funciones, pero por ahora nos concentraremos en un tipo simple. Aquí hemos definido una función usando la palabra clave function, seguida de un nombre, con paréntesis después de él. Después de eso ponemos dos llaves ({ }). Dentro de las llaves se encuentra todo el código que queremos ejecutar cuando llamamos a la función.

+ +

Cuando queramos ejecutar el código, escribimos el nombre de la función seguido de los paréntesis.

+ +

Probémoslo ahora. Guarda tu código y actualiza la página en tu navegador. Luego, ingresa a la consola JavaScript de las herramientas para desarrolladores e ingresa la siguiente línea:

+ +
checkGuess();
+ +

Después de presionarRetorno/Intro, debería aparecer una alerta que dice "Soy un marcador de posición"; hemos definido una función en nuestro código que crea una alerta cada vez que la llamamos.

+ +
+

Nota: Aprenderás mucho más sobre las funciones más adelante en el curso.

+
+ +

Operadores

+ +

Los operadores de JavaScript nos permiten realizar pruebas, hacer cálculos matemáticos, unir cadenas y otras cosas similares.

+ +

Si aún no lo has hecho, guarda tu código, actualiza la página en tu navegador y abre la consola JavaScript de las herramientas para desarrolladores. Luego, podemos intentar escribir los ejemplos que se muestran a continuación — escribe cada una de las columnas de "Ejemplo" exactamente como se muestra, presionando Retorno/Intro después de cada una, y ve los resultados que devuelven.

+ +

Primero veamos los operadores aritméticos, por ejemplo:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorDescripciónEjemplo
+Suma6 + 9
-Resta20 - 15
*Multiplicación3 * 7
/División10 / 5
+ +

También puedes usar el operador + para unir cadenas de texto (en programación, esto se llama concatenación). Intenta ingresar las siguientes líneas, una por una:

+ +
let name = 'Bingo';
+name;
+let hello = ' dice hola!';
+hello;
+let greeting = '¡' + name + hello;
+greeting;
+ +

También disponemos de algunos atajos de operadores, llamados operadores de asignación mejorada. Por ejemplo, si quieres simplemente agregar una nueva cadena de texto a una existente y devolver el resultado, puedes hacer esto:

+ +
name += ' dice hola!';
+ +

Esto es equivalente a

+ +
name = name + ' dice hola!';
+ +

Cuando ejecutamos pruebas de verdadero/falso (por ejemplo, dentro de condicionales — consulta {{anch("Conditionals", "abajo")}}) usamos operadores de comparación. Por ejemplo:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorDescripciónEjemplo
===Igualdad estricta (¿es exactamente lo mismo?) +
+5 === 2 + 4 // false
+'Chris' === 'Bob' // false
+5 === 2 + 3 // true
+2 === '2' // false; número versus cadena
+
+
!==No igual (¿no es lo mismo?) +
+5 !== 2 + 4 // true
+'Chris' !== 'Bob' // true
+5 !== 2 + 3 // false
+2 !== '2' // true; número versus cadena
+
+
<Menor que +
+6 < 10 // true
+20 < 10 // false
+
>Mayor que +
+6 > 10 // false
+20 > 10  // true
+
+ +

Condicionales

+ +

Volviendo a nuestra función checkGuess(), creo que es seguro decir que no queremos que simplemente muestre un mensaje de marcador de posición. Queremos que compruebe si la respuesta del jugador es correcta o no, y que responda de manera apropiada.

+ +

En este punto, reemplaza su función checkGuess() actual con esta versión:

+ +
function checkGuess() {
+  let userGuess = Number(guessField.value);
+  if (guessCount === 1) {
+    guesses.textContent = 'Intentos anteriores: ';
+  }
+  guesses.textContent += userGuess + ' ';
+
+  if (userGuess === randomNumber) {
+    lastResult.textContent = '¡Felicidades! ¡Lo adivinaste!';
+    lastResult.style.backgroundColor = 'green';
+    lowOrHi.textContent = '';
+    setGameOver();
+  } else if (guessCount === 10) {
+    lastResult.textContent = '!!!Fin del juego!!!';
+    setGameOver();
+  } else {
+    lastResult.textContent = '¡Incorrecto!';
+    lastResult.style.backgroundColor = 'red';
+    if(userGuess < randomNumber) {
+      lowOrHi.textContent = '¡El número es muy bajo!';
+    } else if(userGuess > randomNumber) {
+      lowOrHi.textContent = '¡El número es muy grande!';
+    }
+  }
+
+  guessCount++;
+  guessField.value = '';
+  guessField.focus();
+}
+ +

Esto es un montón de código — ¡uf! Repasemos cada sección y expliquemos lo qué hace.

+ + + +

Eventos

+ +

A estas alturas, hemos implementado correctamente la función checkGuess(), pero no hará nada porque aún no la hemos llamado. Lo ideal, sería llamarla cuando se presiona el botón "Enviar respuesta", y para hacerlo necesitamos usar un evento. Los eventos son cosas que suceden en el navegador — se hace clic en un botón, se carga una página, se reproduce un video, etc. — en respuesta a lo cual podemos ejecutar bloques de código. Las construcciones que escuchan el evento que ocurre se denominan escuchas de eventos, y los bloques de código que se ejecutan en respuesta a la activación del evento se denominan controladores de eventos.

+ +

Agrega la siguiente línea debajo de tu función checkGuess():

+ +
guessSubmit.addEventListener('click', checkGuess);
+ +

Aquí estamos agregando un escucha de eventos al botón guessSubmit. Este es un método toma dos valores de entrada (llamados argumentos) — el tipo de evento que queremos escuchar (en este caso, click) como una cadena, y el código que queremos ejecutar cuando ocurra el evento (en este caso la función checkGuess()). Ten en cuenta que no es necesario especificar los paréntesis al escribirlo dentro de {{domxref("EventTarget.addEventListener", "addEventListener()")}}.

+ +

Intenta guardar y actualizar tu código ahora, y tu ejemplo debería funcionar — hasta cierto punto. El único problema ahora es que si adivinas la respuesta correcta o agotas los intentos, el juego se interrumpirá porque aún no hemos definido la función setGameOver() que se supone se debe ejecutar una vez que el juego se acabó. Ahora, agreguemos nuestro código faltante y completemos la funcionalidad de ejemplo.

+ +

Finalizando la funcionalidad del juego

+ +

Agreguemos la función setGameOver() al final de nuestro código y luego repasémoslo. Agrega esto ahora, debajo del resto de su JavaScript:

+ +
function setGameOver() {
+  guessField.disabled = true;
+  guessSubmit.disabled = true;
+  resetButton = document.createElement('button');
+  resetButton.textContent = 'Iniciar nuevo juego';
+  document.body.append(resetButton);
+  resetButton.addEventListener('click', resetGame);
+}
+ + + +

¡Ahora también necesitamos definir esta función! Agrega el siguiente código, nuevamente al final de tu JavaScript:

+ +
function resetGame() {
+  guessCount = 1;
+
+  const resetParas = document.querySelectorAll('.resultParas p');
+  for (let i = 0 ; i < resetParas.length ; i++) {
+    resetParas[i].textContent = '';
+  }
+
+  resetButton.parentNode.removeChild(resetButton);
+
+  guessField.disabled = false;
+  guessSubmit.disabled = false;
+  guessField.value = '';
+  guessField.focus();
+
+  lastResult.style.backgroundColor = 'white';
+
+  randomNumber = Math.floor(Math.random() * 100) + 1;
+}
+ +

Este bloque de código bastante largo restablece completamente todo a cómo estaba al comienzo del juego, para que el jugador pueda intentarlo de nuevo. Eso:

+ + + +

En este punto, deberías tener un juego completamente funcional (simple) — ¡Felicidades!

+ +

Todo lo que resta por hacer en este artículo es hablar sobre algunas otras importantes características del código que ya has visto, aunque es posible que no te hayas dado cuenta.

+ +

Bucles

+ +

Una parte del código anterior que debemos examinar detalladamente es el bucle for. Los bucles son un muy importante concepto en programación, estos te permiten seguir ejecutando un fragmento de código una y otra vez, hasta que se cumpla una determinada condición.

+ +

Para empezar, de nuevo ve a tu consola JavaScript de las herramientas para desarrolladores del navegador e introduce lo siguiente:

+ +
for (let i = 1 ; i < 21 ; i++) { console.log(i) }
+ +

¿Que sucedió? Los números 1 a 20 se imprimieron en tu consola. Esto se debió al bucle. Un bucle for toma tres valores (argumentos) de entrada:

+ +
    +
  1. Un valor inicial: En este caso, comenzamos a contar en 1, pero este podría ser cualquier número que desees. También puedes reemplazar la letra i con cualquier nombre que desees, pero por convención se usa i porque es corto y fácil de recordar.
  2. +
  3. Una condición de salida: Aquí hemos especificado i < 21 — el ciclo continuará hasta que i no sea menor que 21. Cuando i llegue a 21, el bucle ya no se ejecutará.
  4. +
  5. Un incremento: Hemos especificado i++, que significa "agrega 1 a i". El ciclo se ejecutará una vez por cada valor de i, hasta que i alcance un valor de 21 (como se explicó anteriormente). En este caso, simplemente imprimimos el valor de i en la consola en cada iteración usando {{domxref("console.log", "console.log()")}}.
  6. +
+ +

Ahora veamos el ciclo en nuestro juego de adivinan el número — lo siguiente está dentro de la función resetGame():

+ +
const resetParas = document.querySelectorAll('.resultParas p');
+for (let i = 0 ; i < resetParas.length ; i++) {
+  resetParas[i].textContent = '';
+}
+ +

Este código crea una variable que contiene una lista de todos los párrafos dentro de <div class="resultParas"> usando el método {{domxref("document.querySelectorAll", "querySelectorAll()")}}, luego recorre cada uno de ellos, eliminando el texto contenido a su paso.

+ +

Una pequeña explicación sobre objetos.

+ +

Agreguemos una mejora final más antes de entrar en esta explicación. Agrega la siguiente línea justo debajo de la línea let resetButton; cerca de la parte superior de tu JavaScript, luego guarda tu archivo:

+ +
guessField.focus();
+ +

Esta línea usa el método {{domxref("HTMLElement.focus", "focus()")}} para colocar automáticamente el cursor en el campo de texto {{htmlelement("input")}} tan pronto como se cargue la página, lo cual significa que el jugador puede comenzar a escribir su primer intento inmediatamente, sin tener que hacer clic primero en el campo del formulario. Es solo una pequeña adición, pero mejora la experiencia del jugador — brindando al usuario una buena pista visual de lo que tiene que hacer para jugar.

+ +

Analicemos lo que está sucediendo aquí con un poco más de detalle. En JavaScript, todo es un objeto. Un objeto es una colección de funciones relacionadas almacenadas en un solo grupo. Puedes crear tus propios objetos, pero eso es bastante avanzado y no lo cubriremos hasta mucho más adelante en el curso. Por ahora, analizaremos brevemente los objetos integrados que contiene tu navegador, los cuales te permiten hacer muchas cosas útiles.

+ +

En este caso particular, primero creamos una constante guessField que almacena una referencia al campo de texto del formulario en nuestro HTML — la siguiente línea se puede encontrar entre nuestras declaraciones cerca de la parte superior del código:

+ +
const guessField = document.querySelector('.guessField');
+ +

Para obtener esta referencia, usamos el método {{domxref("document.querySelector", "querySelector()")}} del objeto {{domxref("document")}}. querySelector() toma un parámetro — un selector CSS que selecciona el elemento del que deseas una referencia.

+ +

Debido a que guessField ahora contiene una referencia a un elemento {{htmlelement("input")}}, ahora tiene acceso a varias propiedades (básicamente variables almacenadas dentro de los objetos, algunas de las cuales no les puedes cambiar sus valores) y métodos (básicamente funciones almacenadas dentro de objetos). Un método disponible para elementos input es focus(), por lo que ahora podemos usar esta línea para enfocar el campo de texto:

+ +
guessField.focus();
+ +

Las variables que no contienen referencias a elementos de formulario no dispondrán de método focus(). Por ejemplo, la constante guessCount contiene una referencia a un elemento {{htmlelement("p")}} y la variable guessCount contiene un número.

+ +

Jugando con los objetos del navegador

+ +

Juguemos un poco con algunos objetos del navegador.

+ +
    +
  1. En primer lugar, abre tu programa en un navegador.
  2. +
  3. A continuación, abre las herramientas de desarrollo del navegador y asegúrate de que la pestaña de la consola JavaScript esté abierta.
  4. +
  5. Escribe guessField y la consola te mostrará que la variable contiene un elemento {{htmlelement("input")}}. También notarás que la consola te ayuda completando automáticamente los nombres de los objetos que existen dentro del entorno de ejecución, ¡incluidas tus variables!
  6. +
  7. Ahora escribe lo siguiente: +
    guessField.value = 'Hola';
    + La propiedad value representa el valor actual ingresado en el campo de texto. Verás que al ingresar este comando, ¡hemos cambiado este valor!
  8. +
  9. Ahora intenta escribir guesses en la consola y presiona Intro. La consola te muestra que la variable contiene un elemento {{htmlelement("p")}}.
  10. +
  11. Ahora intenta ingresar la siguiente línea: +
    guesses.value
    + El navegador devuelve undefined, porque los párrafos no tienen la propiedad value.
  12. +
  13. Para cambiar el texto dentro de un párrafo, necesitas la propiedad {{domxref("Node.textContent", "textContent")}} en su lugar. Prueba esto: +
    guesses.textContent = '¿Dónde está mi párrafo?';
    +
  14. +
  15. Ahora, solo por diversión. Intenta ingresar las siguientes líneas, una por una: +
    guesses.style.backgroundColor = 'yellow';
    +guesses.style.fontSize = '200%';
    +guesses.style.padding = '10px';
    +guesses.style.boxShadow = '3px 3px 6px black';
    + Cada elemento de una página tiene una propiedad style, que a su vez contiene un objeto cuyas propiedades contienen todos los estilos CSS en línea aplicados a ese elemento. Esto nos permite establecer dinámicamente nuevos estilos CSS en elementos utilizando JavaScript.
  16. +
+ +

Terminamos por ahora...

+ +

Así que eso es todo para construir el ejemplo. Llegaste al final, ¡bien hecho! Prueba tu código final, o juega con nuestra versión final aquí. Si no puedes hacer que el ejemplo funcione, compáralo con el código fuente.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}

+ +

En este modulo

+ + diff --git a/files/es/learn/javascript/first_steps/arrays/index.html b/files/es/learn/javascript/first_steps/arrays/index.html new file mode 100644 index 0000000000..cea00871a7 --- /dev/null +++ b/files/es/learn/javascript/first_steps/arrays/index.html @@ -0,0 +1,665 @@ +--- +title: Arrays +slug: Learn/JavaScript/First_steps/Arrays +translation_of: Learn/JavaScript/First_steps/Arrays +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}
+ +

Arreglos o Matrices

+ +

En este último artículo de este módulo, veremos las matrices — una manera ordenada de almacenar una lista de elementos de datos bajo un solo nombre de variable. Aquí vemos por qué esto es útil, luego exploramos cómo crear una matriz, recuperar, agregar y eliminar elementos almacenados en una matriz, y más.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, una comprensión básica de HTML y CSS, una idea de lo que es JavaScript.
Objectivo:Para entender qué son las matrices y cómo manipularlas en JavaScript.
+ +

¿Qué es una matriz?

+ +

Las matrices se describen como "objetos tipo lista"; básicamente son objetos individuales que contienen múltiples valores almacenados en una lista. Los objetos de matriz pueden almacenarse en variables y tratarse de la misma manera que cualquier otro tipo de valor, la diferencia es que podemos acceder individualmente a cada valor dentro de la lista y hacer cosas útiles y eficientes con la lista, como recorrerlo con un bucle y hacer una misma cosa a cada valor. Tal vez tenemos una serie de productos y sus precios almacenados en una matriz, y queremos recorrerlos e imprimirlos en una factura, sumando todos los precios e imprimiendo el total en la parte inferior.

+ +

Si no tuvieramos matrices, tendríamos que almacenar cada elemento en una variable separada, luego llamar al código que hace la impresión y agregarlo por separado para cada artículo. Esto sería mucho más largo de escribir, menos eficiente y más propenso a errores. si tuviéramos 10 elementos para agregar a la factura, ya sería suficientemente malo, pero ¿ qué pasa con 100 o 1000 artículos? Volveremos a este ejemplo más adelante en el artículo.

+ +

Como en artículos anteriores, aprendamos sobre los aspectos básicos reales de las matrices ingresando algunos ejemplos en una consola de JavaScript. A continuación proporcionamos uno (también puedes abrir en consola en una pestaña o ventana separadas, o usar la consola de desarrollador de navegador, si lo prefieres).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Creando una matriz

+ +

Las matrices se construyen con corchetes, que contiene una lista de elementos separdos por comas.

+ +
    +
  1. Digamos que queríamos almacenar una lista de compras en una matriz — haríamos algo como lo siguiente. Ingresa las siguientes líneas en la consola: +
    let shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
    +shopping;
    +
  2. +
  3. En este caso, cada elemento de la matriz es una cadena, pero ten en cuenta que puedes almacenar cualquier elemento en una matriz — cadena, número, objeto, otra variable, incluso otra matriz. También puedes mezclar y combinar tipos de elementos — no todos tienen que ser números, cadenas, etc. Prueba estos: +
    let sequence = [1, 1, 2, 3, 5, 8, 13];
    +let random = ['tree', 795, [0, 1, 2]];
    +
  4. +
  5. Intenta creando un par de matrices por tu cuenta, antes de continuar.
  6. +
+ +

Accediendo y modificando elementos de la matriz

+ +

Puedes entonces acceder a elementos individuales en la matriz mediante la notación de corchetes, del mismo modo que accediste a las letras de una cadena.

+ +
    +
  1. Ingresa lo siguiente en tu consola: +
    shopping[0];
    +// returns "bread"
    +
  2. +
  3. también puedes modificar un elemento en una matriz simplemente dando a un item de la matriz un nuevo valor. Prueba esto: +
    shopping[0] = 'tahini';
    +shopping;
    +// shopping will now return [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    + +
    Nota: Lo dijimos antes, pero solo como recordatorio — ¡ las computadoras comienzan a contar desde 0!
    +
  4. +
  5. Ten en cuenta que una matriz dentro de otra matriz se llama matriz multidimensional. Puedes acceder a los elementos de una matriz que estén dentro de otra, encadenando dos pares de corchetes. Por ejemplo, para acceder a uno de los elementos dentro de la matriz, que a su vez, es el tercer elemento dentro de la matriz random (ver sección anterior), podríamos hacer algo como esto: +
    random[2][2];
    +
  6. +
  7. Intenta seguir jugando y haciendo algunas modificaciones más a tus ejemplos de matriz antes de continuar.
  8. +
+ +

Encontrar la longitud de una matriz

+ +

Puedes averiguar la longitud de una matriz (cuántos elementos contiene) exactamente de la misma manera que determinas la longitud (en caracteres) de una cadena— utilizando la propiedad {{jsxref("Array.prototype.length","length")}}. Prueba lo siguiente:

+ +
sequence.length;
+// should return 7
+ +

Esto tiene otros usos, pero se usa más comunmente para indicarle a un ciclo que continúe hasta que haya recorrido todos los elementos de la matriz. Así por ejemplo:

+ +
let sequence = [1, 1, 2, 3, 5, 8, 13];
+for (var i = 0; i < sequence.length; i++) {
+  console.log(sequence[i]);
+}
+ +

Aprenderás acerca de bucles correctamente en un artículo futuro, pero brevemente, éste código dice:

+ +
    +
  1. Comienza el bucle en el elemento de la posición 0 en la matriz.
  2. +
  3. Detén el bucle en el número de item igual a la longitud de la matriz. Esto funcionará para una matriz de cualquier longitid, pero en este caso el ciclo se detendrá en el elemento número 7 (esto es bueno, ya que el último elemento — que queremos que recorra el bucle — es 6.
  4. +
  5. Para cada elemento, imprime en la consola del navegador con console.log().
  6. +
+ +

Alguno métodos de matriz útiles

+ +

En esta sección veremos algunos métodos bastante útiles relacionados con matrices que nos permiten dividir cadenas en elementos de matriz y viceversa, y agregar nuevos elementos en matrices.

+ +

Conversión entre matrices y cadenas

+ +

A menudo se te presentarán algunos datos brutos contenidos en una cadena larga y grande, y es posible que desees separar los elementos útiles de una forma más conveniente y luego hacerle cosas, como mostrarlos en una tabla de datos. Para hacer esto, podemos usar el método {{jsxref("String.prototype.split()","split()")}}. En su forma más simple, esto toma un único parámetro, el caracter que quieres separar de la cadena, y devuelve las subcadenas entre el separador como elementos en una matriz.

+ +
+

Nota: Bien, esto es técnicamente un método de cadena, no un método de matriz, pero lo hemos incluido con las matrices, ya que va bien aquí.

+
+ +
    +
  1. Vamos a jugar con esto, para ver como funciona. Primero, crea una cadena en tu consola: +
    let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
    +
  2. +
  3. Ahora dividámoslo en cada coma: +
    let myArray = myData.split(',');
    +myArray;
    +
  4. +
  5. Finalmente, intenta encontrar la longitud de tu nueva matriz y recuperar algunos elementos de ella: +
    myArray.length;
    +myArray[0]; // the first item in the array
    +myArray[1]; // the second item in the array
    +myArray[myArray.length-1]; // the last item in the array
    +
  6. +
  7. También puedes ir en la dirección opuesta usando el método {{jsxref("Array.prototype.join()","join()")}}. Prueba lo siguiente: +
    let myNewString = myArray.join(',');
    +myNewString;
    +
  8. +
  9. Otra forma de convertir una matriz en cadena es usar el método {{jsxref("Array.prototype.toString()","toString()")}}. toString() es posiblemente  más simple que join() ya que no toma un parámetro, pero es más limitado. Con join() puedes especificar diferentes separadores (intenta ejecutar el Paso 4 con un caracter diferente a la coma). +
    let dogNames = ['Rocket','Flash','Bella','Slugger'];
    +dogNames.toString(); //Rocket,Flash,Bella,Slugger
    +
  10. +
+ +

Agregar y eliminar elementos de la matriz

+ +

Todavia no hemos cubierto la posibilidad de agregar y eliminar elementos de la matriz — echemos un vistazo a esto ahora. Usaremos la matriz myArray con la que terminamos en la última sección. Si todavía no has seguido esa sección, primero crea la matriz en tu consola:

+ +
let myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];
+ +

Antes que nada, para añdir o eliminar un elemento al final de una matriz podemos usar {{jsxref("Array.prototype.push()","push()")}} y {{jsxref("Array.prototype.pop()","pop()")}} respectivamente.

+ +
    +
  1. primero usemos push() — nota que necesitas incluir uno o más elementos que desees agregas al final de tu matriz. Prueba esto: + +
    myArray.push('Cardiff');
    +myArray;
    +myArray.push('Bradford', 'Brighton');
    +myArray;
    +
    +
  2. +
  3. La nueva longitud de la matriz se devuelve cuando finaliza la llamada al método. Si quisieras almacenar la nueva longitud de matriz en una variable, podrías hacer algo como esto: +
    let newLength = myArray.push('Bristol');
    +myArray;
    +newLength;
    +
  4. +
  5. Eliminar el último elemento de una matriz es tan simple como ejecutar pop() en ella. Prueba esto: +
    myArray.pop();
    +
  6. +
  7. El elemento que sé eliminó se devuelve cuando se completa la llamada al método. Para guardar este elemento en una variable, puedes hacer lo siguiente: +
    let removedItem = myArray.pop();
    +myArray;
    +removedItem;
    +
  8. +
+ +

{{jsxref("Array.prototype.unshift()","unshift()")}} y {{jsxref("Array.prototype.shift()","shift()")}} funcionan exactamente igual de push() y pop(), respectivamente, excepto que funcionan al principio de la matriz, no al final.

+ +
    +
  1. Primero unshift() — prueba el siguiente comando: + +
    myArray.unshift('Edinburgh');
    +myArray;
    +
  2. +
  3. Ahora shift(); prueba estos! +
    let removedItem = myArray.shift();
    +myArray;
    +removedItem;
    +
  4. +
+ +

Aprendizaje activo: ¡Imprimiendo esos productos!

+ +

Volvamos al ejemplo que describimos anteriormente — imprima los nombres de los productos y los precios en una factura, luego, sume los precios e imprímelos en la parte inferior. En el ejemplo editable a continuación, hay comentarios que contienen números — cada uno de estos marca un lugar donde debe agregar algo al código. Ellos son los siguientes:

+ +
    +
  1. Debajo de // number 1 hay un número de cadena, cada una de las cuales contiene un nombre de producto y un precio separados por dos puntos. Nos gustaría que conviertas esto en una matriz y lo almacenamos en una matriz llamda products.
  2. +
  3. En la misma línea que el comentario // number 2 es el comienzo de un ciclo for. En esta línea, actualmente tenemos i <= 0, que es una prueba condicional que hace que el bucle que el bucle for se detenga inmediatamente, porque dice "detener cuando i es menor o igual 0", y  i comienza en 0. Nos gustaría que reemplazaras esto con una prueba condicional que detenga el ciclo cuando i no sea inferior a la longitud la matriz products .
  4. +
  5. justo debajo del comentario // number 3 queremos que escriba una línea de código que divide el elemento actual de la matriz (nombre:precio) en dos elementos separados, uno que contiene solo el nombre y otros que contienen solo el precio. Si no está seguro de cómo hacerlo, consulte el artículo Métodos de cadenas útiles para obtener ayuda o, mejor aún, consulte la sección {{anch("Converting between strings and arrays")}} de este artículo.
  6. +
  7. Como parte de la línea de código anterior, también querras convertir el precio de una cadena a un número. Si no pudes recordar como hacerlo, consulta el primer artículo de cadenas.
  8. +
  9. Hay una variable llamada total que se crea y se le da un valor de 0 en la parte superior del código. Dentro del ciclo (debajo de // number 4) queremos que agregues una línea que añade el precio actual del artículo a ese total en cada iteración del ciclo, de modo que al final del código el total correcto se imprima en la factura. Es posible que necesites un operador de asignación para hacer esto.
  10. +
  11. Queremos que cambies la línea justo de bajo // number 5 para que la variable itemText se iguale a "nombre de elemnto actual — $precio de elemento actual", por ejemplo "Zapatos — $23.99" en cada caso, por lo que la ionformación correcta artículo está impreso en la factura. Esto es simplemente una concatenación de cadenas, lo que debería ser familiar para ti.
  12. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}

+ +

Aprendizaje Activo: Top 5 búsquedas

+ +

Un buen uso para los métodos de matriz como {{jsxref("Array.prototype.push()","push()")}} y {{jsxref("Array.prototype.pop()","pop()")}} es cuando estás manteniendo un registro de elementos actualmente activos en una aplicación web. En una escena animada por ejemplo, es posible que tengas una matriz de objetos que representan los gráficos de fondo que se muestran actualmente, y es posible que sólo desees que se muestren 50 a la vez, por razones de rendimiento o desorden. A medida que se crean y agregan nuevos objetos a la matriz, se puede eliminar los más antiguos de la matriz para mantener el número deseado.

+ +

En este ejemplo vamos a mostrar un uso mucho más simple — aquí te daremos un sitio de búsqueda falso, con un cuadro de búsqueda. La idea es que cuando los términos se ingresan en un cuadro de búsqueda, se muetren el top 5 de términos de búsqueda previos en la lista. Cuando el número de términos supera el 5, el último término comienza a borrarse cada vez que agregas un nuevo término a la parte superior, por lo que siempre se muestran los 5 términos anteriores.

+ +
+

Nota: En una aplicación de búsqueda real, probablemente puedas hacer clic en los términos de búsqueda anteriores para volver a los términos de búsqueda anteriores y ¡se motrarán los resultados de búsqueda reales! Solamente lo mantendremos simple por ahora.

+
+ +

Para completar la aplicación necesitamos:

+ +
    +
  1. Agregar una línea debajo del comentario // number 1 que agrega el valor actual ingresado en la entrada de la búsqueda al inicio de la matriz. Esto se puede recuperar usando searchInput.value.
  2. +
  3. Agrega una línea debajo del comentario // number 2 que elimina el valor actualmente al final de la matriz.
  4. +
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}

+ +

Conclusión

+ +

Después de leer este artículo, estamos seguros de que estaras de acuerdo en que las matrices parecen bastante útiles; las verás aparecer en todas partes en JavaScript, a menudo en asociación con bucles para hacer una misma cosa con cada elemento de la matriz. Te enseñaremos todos los aspectos básicos útiles que hay que conocer sobre los bucles en el siguiente módulo, pero por ahora debes darte un aplauso y tomarte un merecido descanso; ¡has trabajado en todos los artículos de este módulo!

+ +

Lo único que queda por hacer es trabajar a través de la evaluación de este módulo, que te pondrá a prueba tu comprensión de los de los artículos anteriores.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/generador_de_historias_absurdas/index.html b/files/es/learn/javascript/first_steps/generador_de_historias_absurdas/index.html new file mode 100644 index 0000000000..58bb8e688a --- /dev/null +++ b/files/es/learn/javascript/first_steps/generador_de_historias_absurdas/index.html @@ -0,0 +1,147 @@ +--- +title: Generador de historias absurdas +slug: Learn/JavaScript/First_steps/Generador_de_historias_absurdas +tags: + - Arreglos + - Cadenas + - JavaScript + - Numeros + - Principiante +translation_of: Learn/JavaScript/First_steps/Silly_story_generator +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

+ +

En esta evaluación, deberás tomar parte del conocimiento que has aprendido en los artículos de este módulo y aplicarlo a la creación de una aplicación divertida que genere historias aleatorias. ¡Que te diviertas!

+ + + + + + + + + + + + +
Prerrequisitos:Antes de intentar esta evaluación, deberías haber revisado todos los artículos de este módulo.
Objetivo:Probar la comprensión de los fundamentos de JavaScript, como variables, números, operadores, cadenas y matrices
+ +

Punto de partida

+ +

Para iniciar esta evaluación, debe:

+ + + +
+

Nota: Alternativamente, puede usar un sitio como JSBinThimble para hacer su evaluación. Puede pegar el HTML, CSS y JavaScript en uno de estos editores en línea. Si el editor en línea que está utilizando no tiene un panel de JavaScript separado, no dude en colocarlo en línea en un elemento <script> dentro de la página HTML.

+
+ +

Resumen del proyecto

+ +

Se le han proporcionado algunos HTML / CSS en bruto y algunas cadenas de texto y funciones de JavaScript; necesita escribir el JavaScript necesario para convertir esto en un programa de trabajo, que hace lo siguiente:

+ + + +

La siguiente captura de pantalla muestra un ejemplo de lo que debería producir el programa terminado:

+ +

+ +

Para darle más idea, eche un vistazo al ejemplo final (¡no mire el código fuente!)

+ +

Etapas para completar

+ +

En las siguientes secciones se describe lo que hay que hacer.

+ +

Configuración básica:

+ +
    +
  1. Crear un nuevo archivo llamado main.js, en el mismo directorio que tu archivo index.html.
  2. +
  3. Aplicar el archivo JavaScript externo a tu HTML insertando un elemento {{htmlelement("script")}} en tu HTML haciendo referencia a main.js. Póngalo justo antes de la etiquette de cierra </body>.
  4. +
+ +

Variables y funciones iniciales:

+ +
    +
  1. en el archivo de texto sin procesar, copia todo el código bajo el encabezado "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" y pégalo en la parte superior del archivo main.js. Esto te dará tres variables que almacenan las referencias al campo de texto "Enter custom name" (customName), el botón "Generate random story" (randomize), y el elemento {{htmlelement("p")}} al fondo del cuerpo HTML en el que la historia será copiada en (story), respectivamente. Además, obtendrás una funcion llamada randomValueFromArray() que toma un array, y devuelve uno de los items guardados dentro del array al azar.
  2. +
  3. Ahora observa la segunda sección del archivo de texto sin procesar — "2. RAW TEXT STRINGS". Esta contiene cadenas de texto que actuarán como entrada en nuestro programa. Nos gustaría que mantengas estas variables internas dentro del archivo main.js: +
      +
    1. Almacena la primera, la más larga, cadena de texto dentro de una variable llamada storyText.
    2. +
    3. Almacena el primer conjunto de tres cadenas dentro de un array llamado insertX.
    4. +
    5. Almacena el segundo conjunto de tres cadenas dentro de un array llamado insertY.
    6. +
    7. Almacena el tercer conjunto de tres cadenas dentro de un array llamado insertZ.
    8. +
    +
  4. +
+ +

Colocar el controlador de evento y la función incompleta:

+ +
    +
  1. Ahora regresa al archivo de texto sin procesar.
  2. +
  3. Copia el código encontrado bajo el encabezado "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" y pégalo al fondo de tu archivo main.js . Esto: +
      +
    • Añade un detector de eventos a la variable randomize, de manera que cuando al botón que esta representa se le haya dado un click, la función result() funcione.
    • +
    • Añade una definición de la función parcialmente completada result() a tu código. Por el resto de la evaluación, deberás llenar en líneas dentro de esta función para completarla y hacer que trabaje adecuadamente.
    • +
    +
  4. +
+ +

Completando la función result():

+ +
    +
  1. Crear una nueva variable llamada newStory, y establezca su valor igual a storyText. Esto es necesario para que podamos crear una nueva historia aleatoria cada vez que se presiona el botón y se ejecuta la función. Si hiciéramos cambios directamente en storyText, solo podríamos generar una nueva historia una vez.
  2. +
  3. Crear tres nuevas variables llamadas xItem, yItem, y zItem, y tienes que igualar cada variable llamando a randomValueFromArray() en sus tres matrices (el resultado en cada caso será un elemento aleatorio de cada matriz en la que se llama). Por ejemplo, puede llamar a la función y hacer que devuelva una cadena aleatoria de  insertX escribiendo randomValueFromArray(insertX).
  4. +
  5. A continuación, queremos reemplazar los tres marcadores de posición en la cadena newStory:insertx:, :inserty:, y :insertz: — con las cadenas almacenadas en xItem, yItem, y zItem. Hay un método de string en particular que lo ayudará aquí: en cada caso, haga que la llamada al método sea igual a newStory de modo que cada vez que se llame, newStory se iguale a sí mismo, pero con sustituciones. Entonces, cada vez que se presiona el botón, estos marcadores de posición se reemplazan con una cadena absurda aleatoria. Como sugerencia adicional, el método en cuestión solo reemplaza la primera instancia de la subcadena que encuentra, por lo que es posible que deba realizar una de las llamadas dos veces.
  6. +
  7. Dentro del primer bloque if, agregue otra llamada al método de reemplazo de cadena para reemplazar el nombre 'Bob' que se encuentra en la cadena newStory con la variable de name. En este bloque estamos diciendo "Si se ingresó un valor en la entrada de texto customName  reemplace a Bob en la historia con ese nombre personalizado."
  8. +
  9. Dentro del segundo bloque if, se esta verificando si se ha seleccionado el botón de opción uk  Si es así, queremos convertir los valores de peso y temperatura en la historia de libras and Fahrenheit a stones and grados centígrados. Lo que debe hacer es lo siguiente: +
      +
    1. Busque las fórmulas para convertir libras a stone, and Fahrenheit en grados centígrados.
    2. +
    3. Dentro de la línea que define la variable de weight, reemplace 300 con un cálculo que convierta 300 libras en stones. Concatenar 'stone' al final del resultado de la llamada Math.round().
    4. +
    5. Al lado de la línea que define la variable de temperature, reemplace 94 con un cálculo que convierta 94 Fahrenheit en centígrados. Concatenar 'centigrade' al final del resultado de la llamada Math.round().
    6. +
    7. Justo debajo de las dos definiciones de variables, agregue dos líneas de reemplazo de cadena más que reemplacen '94 fahrenheit 'con el contenido de la variable de temperature, y  '300 libras' con el contenido de la variable de weight.
    8. +
    +
  10. +
  11. Finalmente, en la penúltima línea de la función, haga que la propiedad textContent de la variable de la story (que hace referencia al párrafo) sea igual a newStory.
  12. +
+ +

Claves y pistas

+ + + +

Evaluación o ayuda adicional

+ +

Si está siguiendo esta evaluación como parte de un curso organizado, debería poder entregar su trabajo a su profesor/mentor para que lo califique. Si está aprendiendo por ti mismo, puede obtener la guía de calificación con bastante facilidad preguntando en el hilo de discussion thread for this exercise, o en el canal de IRC #mdn en Mozilla IRC. Pruebe el ejercicio primero: ¡no se gana nada haciendo trampa!

+ +

{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/index.html b/files/es/learn/javascript/first_steps/index.html new file mode 100644 index 0000000000..9a1211fc54 --- /dev/null +++ b/files/es/learn/javascript/first_steps/index.html @@ -0,0 +1,88 @@ +--- +title: Primeros pasos con JavaScript +slug: Learn/JavaScript/First_steps +tags: + - Arrays + - Arreglos + - Artículo + - Cadenas + - CodingScripting + - Evaluación + - Guide + - Guía + - JavaScript + - Landing + - Matemáticas + - Numeros + - Operadores + - Principiante + - Rangos + - Series + - TopicStub + - Variables + - 'l10n:priority' + - modulo +translation_of: Learn/JavaScript/First_steps +--- +
{{LearnSidebar}}
+ +

En nuestro primer módulo de JavaScript, primero respondemos algunas preguntas fundamentales como "¿qué es JavaScript?", "¿cómo se ve?" y "¿qué puede hacer?", antes de pasar avanzar en la guía por tu primera experiencia práctica de escribir JavaScript. Después de eso, explicaremos en detalle algunos bloques de construcción clave, tal como variables, cadenas, números y arreglos.

+ +
+

¿Quieres transformarte en un desarrollador de la interfaz de usuario web?

+ +

Se elaboró un curso que incluye toda la información esencial que necesitas para alcanzar tu objetivo.

+ +

Empieza aquí

+
+ +

Prerrequisitos

+ +

Antes de comenzar este módulo, no necesitas ningún conocimiento previo de JavaScript, pero debes estar familiarizado con HTML y CSS. Es recomendable trabajar con los siguientes módulos antes de comenzar con JavaScript:

+ + + +
+

Nota: Si estás trabajando en una computadora, tableta u otro dispositivo en el que no puedes crear tus propios archivos, puedes probar (la mayoría de) los ejemplos de código en un programa de codificación en línea como JSBin o Glitch.

+
+ +

Guías

+ +
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Que_es_JavaScript", "¿Qué es JavaScript?")}}
+
¡Bienvenido al curso de JavaScript para principiantes de MDN!, En este primer artículo, analizaremos JavaScript desde un alto nivel, respondiendo preguntas como "¿qué es?", y "¿qué hace?", asegurándote de que te sientas cómodo con la intención de JavaScript.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/A_first_splash", "Una primera introducción a JavaScript")}}
+
Ahora que has aprendido algo sobre la teoría de JavaScript y lo que puedes hacer con él, te daremos un curso intensivo sobre las características básicas de JavaScript a través de un tutorial completamente práctico. Aquí, te llevaremos paso a paso en la creación de un sencillo juego de "Adivina el número".
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/What_went_wrong", "¿Qué salió mal? — Solución de problemas de JavaScript")}}
+
Cuando construiste el juego "Adivina el número" en el artículo anterior, es posible que hayas descubierto que no funcionó. Tranquilo — este artículo tiene como objetivo evitar tu calvicie prematura al jalarte los pelos por este tipo de problemas proporcionándote algunos sencillos consejos sobre cómo encontrar y corregir errores en los programas JavaScript.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Variables", "Almacenar la información que necesitas — Variables")}}
+
Después de leer los últimos artículos, deberías saber qué es JavaScript, qué puede hacer por ti, cómo usarlo junto con otras tecnologías web y cómo se ven sus características principales desde un alto nivel. En este artículo llegaremos a los conceptos básicos reales, y veremos cómo trabajar con los bloques de construcción más básicos de JavaScript — Variables.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Math", "Matemáticas básicas en JavaScript — números y operadores")}}
+
En este punto del curso, explicaremos las matemáticas en JavaScript — cómo podemos combinar operadores y otras características para manipular con éxito los números para cumplir nuestras ofertas.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Strings", "Manejo de texto — cadenas en JavaScript")}}
+
A continuación, centraremos nuestra atención en las cadenas (strings) — así es como se llaman los fragmentos de texto en programación. En este artículo, veremos todas las cosas comunes que realmente debes saber sobre las cadenas al aprender JavaScript, como crear cadenas, escapar las comillas en una cadena y unirlas.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Useful_string_methods", "Útiles métodos de cadena")}}
+
Ahora que hemos visto los conceptos básicos de las cadenas, avancemos un poco y comencemos a pensar en las operaciones útiles que podemos hacer en las cadenas con métodos integrados, como encontrar la longitud del texto en una cadena, unir y dividir cadenas, sustituir un caracter por otro en una cadena, y más.
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Arrays", "Arreglos")}}
+
En el artículo final de este módulo, veremos los arreglos — una forma ordenada de almacenar una lista de elementos de datos con un solo nombre de variable. Aquí vemos por qué esto es útil, luego exploramos cómo crear un arreglo, recuperar, agregar y eliminar elementos almacenados en un arreglo, y más.
+
+ +

Evaluaciones

+ +

La siguiente evaluación pondrá a prueba tu comprensión de los conceptos básicos de JavaScript cubiertos en las guías anteriores.

+ +
+
{{web.link("/es/docs/Learn/JavaScript/First_steps/Silly_story_generator", "Generador de historias absurdas")}}
+
En esta evaluación, se te asignará la tarea de tomar algunos de los conocimientos adquiridos en los artículos de este módulo y aplicarlos para crear una divertida aplicación que genere historias absurdas al azar. ¡Que te diviertas!
+
+ +

Ve también

+ +
+
Aprende JavaScript
+
Un excelente recurso para los aspirantes a desarrolladores web — aprende JavaScript en un entorno interactivo, con lecciones breves y pruebas interactivas, guiado por una evaluación automatizada. Las primeras 40 lecciones son gratuitas y el curso completo está disponible por un pequeño pago único.
+
diff --git "a/files/es/learn/javascript/first_steps/matem\303\241ticas/index.html" "b/files/es/learn/javascript/first_steps/matem\303\241ticas/index.html" new file mode 100644 index 0000000000..d9117ed211 --- /dev/null +++ "b/files/es/learn/javascript/first_steps/matem\303\241ticas/index.html" @@ -0,0 +1,443 @@ +--- +title: Matemáticas básicas en JavaScript — números y operadores +slug: Learn/JavaScript/First_steps/Matemáticas +tags: + - Aprender + - Artículo + - Guía + - JavaScript + - Matemáticas + - Math + - Novato + - Operadores + - Principiante + - incremento + - 'l10n:priority' + - modulo +translation_of: Learn/JavaScript/First_steps/Math +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}
+ +

En este punto del curso, hablaremos de matemáticas en JavaScript — cómo  podemos usar {{Glossary("Operator","operadores")}} y otras características para manipular con éxito números y conseguir lo que nos hayamos propuesto.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de ordenadores, comprensión básica de  HTML y CSS, comprensión básica de lo que es JavaScript.
Objetivo:Familiarizarse con las matemáticas básicas de JavaScript.
+ +

Todos aman las matemáticas

+ +

Vale, tal vez no. A algunos nos gustan, otros las odiamos desde que aprendimos en la escuela las tablas de multipicar y las divisiones complicadas, y algunos estamos a mitad entre ambas posturas. Pero ninguno podemos negar que las matemáticas son una parte fundamental de la vida que nos afecta. Y esto es especialmente cierto cuando aprendemos JavaScript (o cualquier otro lenguaje similar) — en la medida en que ello pasa por procesar números, calcular nuevos valores, etc., no te puede sorprender comprobar que JavaScript dispone de un completo conjunto de funciones matemáticas.

+ +

En este artículo se trata solo aquella parte básica que necesitas conocer por ahora.

+ +

Tipos de números

+ +

En programación, incluso el simple sistema numérico decimal que todos conocemos tan bien, es más complicado de lo que podrías pensar. Usamos diferentes términos para describir diferentes tipos de números decimales, por ejemplo:

+ + + +

¡Incluso tenemos distintos tipos de sistemas numéricos! El decimal es base 10 (quiere decir que utiliza 0-9 en cada columna), pero también tenemos cosas como:

+ + + +

Antes de que comiences a preouparte de que tu cerebro se derrita, ¡detente un momento! Para empezar, sólo vamos a apegarnos a los números decimales durante todo este curso; pocas veces te verás en la necesidad de comenzar a pensar sobre los otros tipos, si es que lo haces.

+ +

La segunda parte de las buenas noticias es que, a diferencia de otros lenguajes de programación, JavaScript sólo tiene un tipo de dato para los números, adivinaste, {{jsxref("Number")}}. Esto significa que, sin importar el tipo de número con el que estés lidiando en Javascript, los manejas siempre de la misma manera.

+ +
+

Nota: En realidad, JavaScript tiene un segundo tipo de número, {{Glossary("BigInt")}}, que se utiliza para números enteros muy, muy grandes. Pero para los propósitos de este curso, solo nos preocuparemos por los valores numéricos.

+
+ +

Para mí, todo son números.

+ +

Juguemos un poco con algunos números para ponernos al día con la sintaxis básica que necesitamos. Coloca los comandos listados abajo en la consola JavaScript de tus herramientas para desarrolladores, o utiliza la sencilla consola integrada que verás abajo si lo prefieres.

+ +

Abrir en una ventana nueva

+ +
    +
  1. Primero que todo, declara un par de variables e inicializalas con un entero y un flotante, respectivamente, luego escribe los nombres de esas variables para chequear que todo esté en orden: +
    var myInt = 5;
    +var myFloat = 6.667;
    +myInt;
    +myFloat;
    +
  2. +
  3. Los valores numéricos están escritos sin comillas - Trata de declarar e inicializar un par de variables más que contengan números antes de continuar.
  4. +
  5. Ahora chequea que nuestras variables originales sean del mismo tipo. Hay un operador llamado {{jsxref("Operators/typeof", "typeof")}} en JavaScript hace esto. Digita las dos lineas siguientes: +
    typeof myInt;
    +typeof myFloat;
    + Obtendrás "number" en ambos casos — esto hace las cosas mucho más fáciles que si diferentes números tuvieran difetentes tipos, y tuvimos que lidiar con ellos de diferentes maneras. Uf !
  6. +
+ +

Operadores Aritméticos

+ +

Los operadores aritméticos son operadores básicos que usamos para hacer sumas:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNombrePropósitoEjemplo
+AdiciónSuma dos números juntos.6 + 9
-RestaResta el numero de la derecha del de la izquierda.20 - 15
*MultiplicaciónMultiplica dos números juntos.3 * 7
/DivisiónDivide el número de la izquierda por el de la derecha.10 / 5
%Sobrante (también llamado módulo) +

Retorna el restante después de dividir el número de la izquierda en porciones enteras del de la derecha.

+
8 % 3 (retorna 2, como tres está dos veces en 8, quedando 2 restantes.)
+ +
+

Nota: A veces verás números involucrados en sumas referidas como {{Glossary("Operand", "operands")}}.

+
+ +

Probablemente no necesitemos enseñarte matemáticas básicas, pero nos gustaría probar tu entendimiento de la sintaxis involucrada. Intenta entrar los ejemplos de abajo en tu consola JavaScript de tus herramientas para desarrolladores, o usa la sencilla consola incorporada que se vio anteriormente, si lo prefieres, para familiarizarte con la sintaxis.

+ +
    +
  1. Primero, trata entrando un ejemplo simple por tu cuenta, como +
    10 + 7
    +9 * 8
    +60 % 3
    +
  2. +
  3. Puedes tratar declarando e inicializando algunos números en variables, y probar usándolos en la suma - Las variables se comportarán exactamente como los valores que tienen para los fines de la suma. Por ejemplo: +
    var num1 = 10;
    +var num2 = 50;
    +9 * num1;
    +num2 / num1;
    +
  4. +
  5. Por último, trate entrando algunas expresiones complejas, como: +
    5 + 10 * 3;
    +num2 % 9 * num1;
    +num2 + num1 / 8 + 2;
    +
  6. +
+ +

Es posible que parte de este último conjunto de sumas no te dé el resultado que esperabas; La siguiente sección bien podría dar la respuesta del por qué.

+ +

Precedencia de Operadores

+ +

Veamos el último ejemplo de arriba, asumiendo que num2 tiene el valor 50 y num1 tiene el valor 10 (como se indicó anteriormente):

+ +
num2 + num1 / 8 + 2;
+ +

Como un ser humano, puedes leer esto como "50 más 10 es igual a 60", luego "8 más 2 es igual a 10", y finalmente "60 dividido por 10 es igual a 6".

+ +

Pero el navegador hace "10 dividido por 8 es igual a 1.25", luego "50 más 1.25 más 2 es igual a 53.25".

+ +

Esto es debido a la precedencia de operadores — algunos operadores son aplicados antes de otros cuando se calcula el resultado de una suma (referida como una expresión, en programación).  La precedencia de operadores en JavaScript es la misma que en las matemáticas de la escuela  — La multiplicación y la división se resuelven siempre primero, luego la suma y resta (la suma siempre se evalua de izquierda a derecha).

+ +

Si quieres alterar la precedencia de operación, puedes colocar paréntesis alrededor de las partes que quieras explícitamente evaluar primero. Para obtener un resultado de 6, podríamos hacer esto:

+ +
(num2 + num1) / (8 + 2);
+ +

Pruébalo y verás.

+ +
+

Nota: Una completa lista de todos los operadores de JavaScript y sus precedencias pueden encontrarse en Expresiones y operadores.

+
+ +

Operadores de incremento y decremento

+ +

Algunas veces necesitarás repetidamente sumar o restar uno de/a una variable numérica. Esto puede hacerse convenientemente usando los operadores de incremento (++) y decremento (--). Usamos ++ en nuestro juego "Adivina el número" en nuestro artículo Un primer acercamiento a JavaScript, cuando agregamos 1 a nuestra variable guessCount para mantener una pista de cuantas respuestas le quedan al usuario por turno.

+ +
guessCount++;
+ +
+

Nota: Son muy comunmente usadas en ciclos, que aprenderás más adelante en el curso. Por ejemplo, Digamos que quieras recorrer una lista de precios, y agregar impuestos a cada uno. Usaría un ciclo para recorrer cada valor y realizar el cálculo necesario para agregar el impuesto a las ventas en cada caso. El incrementador es usado para mover al próximo valor cuando es necesario. Damos un simple ejemplo En realidad, proporcionamos un ejemplo simple que muestra cómo se hace esto: ¡pruébalo en vivo y mira el código fuente para ver si puedes detectar los incrementadores! Veremos los ciclos en detalle más adelante en el curso..

+
+ +

Trata jugando con eso en tu consola. Para empezar, nota que no puedes aplicar esto directamente a un número, sin operar en él mismo. Lo siguiente retorna un error:

+ +
3++;
+ +

Asì, puedes solo incrementar una variable existente. Prueba esto:

+ +
var num1 = 4;
+num1++;
+ +

Ok, la extrañeza número 2! Cuando hagas esto, verás que se devuelve un valor de 4; esto se debe a que el navegador devuelve el valor actual y luego incrementa la variable. Puedes ver que se ha incrementado si devuelves el valor variable nuevamente:

+ +
num1;
+ +

Lo mismo funciona con -- : intenta lo siguiente:

+ +
var num2 = 6;
+num2--;
+num2;
+ +
+

Nota: Puedes hacer que el navegador lo haga al revés: aumentar / disminuir la variable y luego devolver el valor, colocando el operador al comienzo de la variable en lugar del final. Prueba los ejemplos anteriores otra vez, pero esta vez usa ++num1 y--num2.

+
+ +

Operadores de asignación

+ +

Los operadores de asignación son operadores que asignan un valor a una variable. Ya usamos el más básico, =, muchas veces — simplemente asigna a la variable de la izquierda, el valor de la derecha:

+ +
var x = 3; // x contiene el valor 3
+var y = 4; // y contiene el valor 4
+x = y; // x ahora contiene el mismo valor de y... 4
+ +

Pero hay algunos tipos más complejos, que proporcionan atajos útiles para mantener tu código más ordenado y más eficiente. Los más comunes se enumeran a continuación.:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNombrePropósito_Ejemplo__Atajo_de__
+=Adición asignaciónSuma el valor de la derecha al valor de la variable de la  izquierda y returna el nuevo valorx = 3;
+ x += 4;
x = 3;
+ x = x + 4;
-=Resta asignación +

Resta el valor de la derecha, del valor de la variable de la izquierda y retorna el nuevo valor.

+
x = 6;
+ x -= 3;
x = 6;
+ x = x - 3;
*=Multiplicación asignación +

Multiplica el valor de la variable en la izquierda por el valor en la derecha y retorna el nuevo valor.

+
x = 2;
+ x *= 3;
x = 2;
+ x = x * 3;
/=División asignación +

Divide el valor de la variable en la izquierda por el valor de la derecha y retorna el nuevo valor.

+
x = 10;
+ x /= 5;
x = 10;
+ x = x / 5;
+ +

Intenta digitar algunos de estos ejemplos en tu consola, para darte una idea de cómo funcionan. Mira si puedes preguntar los valores que tenían antes de ingresarlos en la segunda línea, en cada caso.

+ +

Ten en cuenta que puedes usar otras variables en el lado derecho de cada expresión, por ejemplo:

+ +
var x = 3; // x contiene el valor 3
+var y = 4; // y contiene el valor 4
+x *= y; // x ahora contiene el valor 12
+ +
+

Nota: Hay una cantidad de otros operadores de asignación disponibles, pero estos son los básicos que debes aprender por ahora.

+
+ +

Aprendizaje activo: dimensionando una caja canvas

+ +

En este ejercicio vamos a hacer que completes algunos números y operadores para manipular el tamaño de una caja. El cuadro se dibuja utilizando una API de navegador llamada {{domxref("Canvas API", "", "", "true")}}. No hay necesidad de preocuparse por cómo funciona esto, solo concentrarse en las matemáticas por ahora. El ancho y el alto del cuadro (en píxeles) están definidos por las variables x e y, a las que inicialmente se les asigna un valor de 50.

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}

+ +

Abrir en una nueva ventana

+ +

En el cuadro de código editable anterior, hay dos líneas marcadas claramente con un comentario que nos gustaría que actualices para hacer que el cuadro crezca/se reduzca a ciertos tamaños, utilizando ciertos operadores y/o valores en cada caso. Intenta lo siguiente:

+ + + +

No te preocupes si arruinas totalmente el código. Siempre puedes presionar el botón Restablecer para que las cosas vuelvan a funcionar. Después de haber respondido correctamente a todas las preguntas anteriores, siéntete libre de jugar con el código un poco más, o establece desafíos para tus amigos/compañeros de clase..

+ +

Operadores de comparación

+ +

A veces querremos ejecutar pruebas de verdadero/falso, y luego actuaremos de acuerdo con el resultado de esa prueba. Para ello, utilizamos operadores de comparación.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNombrePropósitoEjemplo
===Igual estrictoComprueba si los valores izquierdo y derecho son idénticos entre sí5 === 2 + 4
!==Igual no-estrictoComprueba si los valores izquierdo y derecho no son idénticos entre sí5 !== 2 + 3
<Menor queComprueba si el valor izquierdo es menor que el derecho.10 < 6
>Mayor queComprueba si el valor izquierdo es mayor que el derecho.10 > 20
<=Menor o igual aComprueba si el valor izquierdo es menor o igual que el derecho.3 <= 2
>=Mayor o igual aComprueba si el valor izquierdo es mayor o igual que el derecho..5 >= 4
+ +
+

Nota: Es posible que algunas personas utilicen == y != en sus pruebas de igualdad y no igualdad. Estos son operadores válidos en JavaScript, pero difieren de === /! ==: la prueba anterior indica si los valores son iguales. pero el tipo de datos puede ser diferente, mientras que las últimas versiones estrictas prueban si el valor y el tipo de datos son los mismos. Las versiones estrictas tienden a reducir el número de errores que no se detectan, por lo que te recomendamos que los utilices.

+
+ +

Si intentas ingresar algunos de estos valores en una consola, verás que todos devuelven valores verdaderos/falsos, esos booleanos que mencionamos en el artículo anterior. Son muy útiles ya que nos permiten tomar decisiones en nuestro código; se usan cada vez que queremos hacer una elección de algún tipo, por ejemplo.:

+ + + +

Veremos cómo codificar dicha lógica cuando veamos declaraciones condicionales en un artículo futuro. Por ahora, veamos un ejemplo rápido:

+ +
<button>Iniciar máquina</button>
+<p>La máquina se detuvo.</p>
+
+ +
var btn = document.querySelector('button');
+var txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+  if (btn.textContent === 'Iniciar máquina') {
+    btn.textContent = 'Detener máquina';
+    txt.textContent = 'La máquina se inició!';
+  } else {
+    btn.textContent = 'Iniciar máquina';
+    txt.textContent = 'La máquina se detuvo.';
+  }
+}
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}

+ +

Abrir en una nueva ventana

+ +

Puede ver el operador de igualdad utilizado justo dentro de la función updateBtn(). En este caso, no estamos probando si dos expresiones matemáticas tienen el mismo valor (estamos comprobando si el contenido de texto de un botón contiene una cadena determinada), pero sigue siendo el mismo principio. Si el botón está actualmente diciendo "Iniciar máquina" cuando se presiona, cambiamos su etiqueta a "Detener máquina" y actualizamos la etiqueta según corresponda. Si el botón está actualmente diciendo "Detener máquina" cuando se presiona, volvemos a cambiar la pantalla.

+ +
+

Nota: Un control de este tipo que intercambia entre dos estados generalmente se conoce como conmutador. Conmuta entre un estado y otro — Luces on, luces off, etc.

+
+ +

Pon a prueba tus habilidades

+ +

Llegaste al final de este artículo, pero ¿puédes recordar la información más importante? Puedes encontrar algunas pruebas para verificar que has comprendido esta información antes de seguir avanzando — Ve ¡Pon a prueba tus habilidades!: Matemáticas.

+ +

Resumen

+ +

En este artículo hemos cubierto la información fundamental que necesitas saber sobre los números en JavaScript, por ahora. Verás los números usados una y otra vez, a lo largo de tu aprendizaje de JavaScript, por lo que es una buena idea hacer esto ahora. Si eres una de esas personas que no disfruta de las matemáticas, puedes sentirte cómodo por el hecho de que este capítulo fue bastante breve.

+ +

En el siguiente artículo, exploraremos el texto y cómo JavaScript nos permite manipularlo.

+ +
+

Nota: Si disfrutas de las matemáticas y quieres leer más sobre cómo se implementa en JavaScript, puedes encontrar muchos más detalles en la sección principal de JavaScript de MDN. Los mejores lugares para iniciar con artículos sobre Numero y fechas y Expresiones y operadores.

+
+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/prueba_tus_habilidades_colon__strings/index.html b/files/es/learn/javascript/first_steps/prueba_tus_habilidades_colon__strings/index.html new file mode 100644 index 0000000000..f919ac1ee3 --- /dev/null +++ b/files/es/learn/javascript/first_steps/prueba_tus_habilidades_colon__strings/index.html @@ -0,0 +1,122 @@ +--- +title: 'Prueba tus habilidades: Strings' +slug: 'Learn/JavaScript/First_steps/Prueba_tus_habilidades:_Strings' +tags: + - Cadenas + - JavaScript + - Novato + - Principiante + - Prueba tus habilidades + - aprende + - strings +translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_Strings' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba de habilidad es evaluar si has entendido nuestros artículos Manejo de texto — cadenas en JavaScript y Métodos de cadena útiles.

+ +
+

Nota: Puedes probar las soluciones en los editores interactivos a continuación, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePen, jsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te quedas atascado, pídenos ayuda — consulta la sección {{anch("Evaluación o ayuda adicional")}} en la parte inferior de esta página.

+
+ +
+

Nota: En los siguientes ejemplos, si hay un error en tu código, se mostrará en el panel de resultados de la página, para ayudarte a intentar averiguar la respuesta (o en la consola JavaScript del navegador, en el caso de la versión descargable).

+
+ +

Cadenas 1

+ +

En nuestra primera tarea de cadenas, comenzaremos con algo pequeño. Ya tienes la mitad de una cita famosa dentro de una variable llamada quoteStart; nos gustaría que:

+ +
    +
  1. Busques la otra mitad de la cita y la agregues al ejemplo dentro de una variable llamada quoteEnd.
  2. +
  3. Concatenes las dos cadenas para hacer una sola cadena que contenga la cita completa. Guardes el resultado dentro de una variable llamada finalQuote.
  4. +
+ +

Verás que obtienes un error en este punto. ¿Puedes solucionar el problema con quoteStart para que la cita completa se muestre correctamente?

+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/strings/strings1.html", '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Cadenas 2

+ +

En esta tarea, se te proporcionan dos variables, quote y substring, que contienen dos cadenas. Nos gustaría que:

+ +
    +
  1. Recuperes la longitud de la cita y la guardes en una variable llamada quoteLength.
  2. +
  3. Busques la posición del índice donde aparece substring en quote, y almacenes ese valor en una variable llamada index.
  4. +
  5. Uses una combinación de las variables que tienes y las propiedades/métodos de cadena disponibles para recortar la cita original a "No me gustan los huevos verdes y el jamón", y la guardes en una variable llamada revisedQuote.
  6. +
+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/strings/strings2.html", '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Cadenas 3

+ +

En la siguiente tarea de cadenas, se te da la misma cita con la que terminaste en la tarea anterior, ¡pero está algo rota! Queremos que la arregles y actualices, así:

+ +
    +
  1. Cambia la letra mayúscula para corregir con mayúscula inicial la oración (todo en minúsculas, excepto la primera letra mayúscula). Almacena la nueva cita en una variable llamada fixedQuote.
  2. +
  3. En fixedQuote, reemplaza "huevos verdes con jamón" con otro alimento que realmente no te guste.
  4. +
  5. Hay una pequeña solución más por hacer: agrega un punto al final de la cita y guarda la versión final en una variable llamada finalQuote.
  6. +
+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/strings/strings3.html", '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Cadenas 4

+ +

En la tarea de cadena final, te hemos dado el nombre de un teorema, dos valores numéricos y una cadena incompleta (los bits que se deben agregar están marcados con asteriscos (*)). Queremos que cambies el valor de la cadena de la siguiente manera:

+ +
    +
  1. Cámbiala de un literal de cadena normal a una plantilla literal.
  2. +
  3. Reemplaza los cuatro asteriscos con cuatro marcadores de posición en la plantilla literal. Estos deben ser: +
      +
    1. El nombre del teorema.
    2. +
    3. Los dos valores numéricos que tenemos.
    4. +
    5. La longitud de la hipotenusa de un triángulo rectángulo, dado que las longitudes de los otros dos lados son iguales a los dos valores que tenemos. Deberás buscar cómo calcular esto a partir de lo que tienes. Haz el cálculo dentro del marcador de posición.
    6. +
    +
  4. +
+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/strings/strings4.html", '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos anteriores.

+ +

Si deseas que se evalúe tu trabajo o estás atascado y deseas pedir ayuda:

+ +
    +
  1. Coloca tu trabajo en un editor que se pueda compartir en línea, como CodePen, jsFiddle o Glitch. Puedes escribir el código tú mismo o utilizar los archivos de punto de partida vinculados en las secciones anteriores.
  2. +
  3. Escribe una publicación solicitando evaluación y/o ayuda en la categoría de aprendizaje del foro de discusión de MDN. Tu publicación debe incluir: +
      +
    • Un título descriptivo como "Se busca evaluación para la prueba de habilidad de Cadenas 1".
    • +
    • Detalles de lo que ya has probado y lo que te gustaría que hiciéramos, p. ej. si estás atascado y necesitas ayuda, o quiere una evaluación.
    • +
    • Un enlace al ejemplo que deseas evaluar o con el que necesitas ayuda, en un editor que se pueda compartir en línea (como se mencionó en el paso 1 anterior). Esta es una buena práctica para entrar — es muy difícil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la página de la tarea o evaluación real, para que podamos encontrar la pregunta con la que deseas ayuda.
    • +
    +
  4. +
diff --git "a/files/es/learn/javascript/first_steps/qu\303\251_es_javascript/index.html" "b/files/es/learn/javascript/first_steps/qu\303\251_es_javascript/index.html" new file mode 100644 index 0000000000..bd845c8681 --- /dev/null +++ "b/files/es/learn/javascript/first_steps/qu\303\251_es_javascript/index.html" @@ -0,0 +1,436 @@ +--- +title: ¿Qué es JavaScript? +slug: Learn/JavaScript/First_steps/Qué_es_JavaScript +tags: + - APIs + - Aprender + - Artículo + - Añadir JavaScript + - Curso + - Dinámico + - En línea + - Gestores de JavaScript en linea + - JavaScript + - Navegador + - Núcleo + - Principiante + - comentários + - externo +translation_of: Learn/JavaScript/First_steps/What_is_JavaScript +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}
+ +

¡Bienvenido al curso de JavaScript para principiantes de MDN! En este artículo veremos JavaScript desde un alto nivel, respondiendo preguntas como "¿Qué es?" y "¿Qué puedes hacer con él?", y asegúrate de estar cómodo con el propósito de JavaScript.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conocimientos básicos de HTML y CSS.
Objetivo:Familiarizarte con lo que es JavaScript, lo que puede hacer y cómo encaja en un sitio web.
+ +

Una definición de alto nivel

+ +

JavaScript es un lenguaje de programación o de secuencias de comandos que te permite implementar funciones complejas en páginas web, cada vez que una página web hace algo más que sentarse allí y mostrar información estática para que la veas, muestra oportunas actualizaciones de contenido, mapas interactivos, animación de Gráficos 2D/3D, desplazamiento de máquinas reproductoras de vídeo, etc., puedes apostar que probablemente JavaScript está involucrado. Es la tercera capa del pastel de las tecnologías web estándar, dos de las cuales (HTML y CSS) hemos cubierto con mucho más detalle en otras partes del Área de aprendizaje.

+ +

+ + + +

Las tres capas se superponen muy bien. Tomemos una etiqueta de texto simple como ejemplo. Podemos marcarla usando HTML para darle estructura y propósito:

+ +
<p>Player 1: Chris</p>
+ +

+ +

Luego, podemos agregar algo de CSS a la mezcla para que se vea bien:

+ +
p {
+  font-family: 'helvetica neue', helvetica, sans-serif;
+  letter-spacing: 1px;
+  text-transform: uppercase;
+  text-align: center;
+  border: 2px solid rgba(0,0,200,0.6);
+  background: rgba(0,0,200,0.3);
+  color: rgba(0,0,200,0.6);
+  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
+  border-radius: 10px;
+  padding: 3px 10px;
+  display: inline-block;
+  cursor: pointer;
+}
+ +

+ +

Y finalmente, podemos agregar algo de JavaScript para implementar un comportamiento dinámico:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('Enter a new name');
+  para.textContent = 'Player 1: ' + name;
+}
+
+ +

{{ EmbedLiveSample('A_high-level_definition', '100%', 80, "", "", "hide-codepen-jsfiddle") }}

+ +

Intenta hacer clic en esta última versión de la etiqueta de texto para ver qué sucede (ten en cuenta también que puedes encontrar esta demostración en GitHub — ¡consulta el código fuente o ejecútalo en vivo)!

+ +

JavaScript puede hacer mucho más que eso — exploremos qué con más detalle.

+ +

Entonces, ¿qué puede hacer realmente?

+ +

El núcleo del lenguaje JavaScript de lado del cliente consta de algunas características de programación comunes que te permiten hacer cosas como:

+ + + +

Sin embargo, lo que aún es más emocionante es la funcionalidad construida sobre el lenguaje JavaScript de lado del cliente. Las denominadas interfaces de programación de aplicaciones (API) te proporcionan superpoderes adicionales para utilizar en tu código JavaScript.

+ +

Las API son conjuntos de bloques de construcción de código listos para usar que permiten a un desarrollador implementar programas que de otro modo serían difíciles o imposibles de implementar. Hacen lo mismo para la programación que los kits de muebles prefabricados para la construcción de viviendas — es mucho más fácil tomar paneles precortados y atornillarlos para hacer una estantería que elaborar el diseño tú mismo, que ir y encontrar la madera correcta, cortar todos los paneles del tamaño y la forma correctos, buscar los tornillos del tamaño correcto y luego júntalos para hacer una estantería.

+ +

Generalmente se dividen en dos categorías.

+ +

+ +

Las APIs del navegador están integradas en tu navegador web y pueden exponer datos del entorno informático circundante o realizar tareas complejas y útiles. Por ejemplo:

+ + + +
+

Nota: Muchas de las demostraciones anteriores no funcionarán en un navegador antiguo — al experimentar, es una buena idea utilizar un navegador moderno como Firefox, Chrome, Edge u Opera para ejecutar tu código. Deberás considerar las pruebas en varios navegadores con más detalle cuando estés más cerca de entregar el código de producción (es decir, código real que usarán los clientes reales).

+
+ +

Las APIs de terceros no están integradas en el navegador de forma predeterminada y, por lo general, debes obtener su código e información de algún lugar de la Web. Por ejemplo:

+ + + +
+

Nota: estas APIs son avanzadas y no cubriremos ninguna de ellas en este módulo. Puedes obtener más información sobre estas en nuestro módulo de APIs web de lado del cliente.

+
+ +

¡También hay mucho más disponible! Sin embargo, no te emociones demasiado todavía. No podrás crear el próximo Facebook, Google Maps o Instagram después de estudiar JavaScript durante 24 horas — hay muchos conceptos básicos que cubrir primero. Y es por eso que estás aquí — ¡sigamos adelante!

+ +

¿Qué está haciendo JavaScript en tu página?

+ +

Aquí, de hecho, comenzaremos a ver algo de código y, mientras lo hacemos, exploraremos lo que realmente sucede cuando ejecutas JavaScript en tu página.

+ +

Recapitulemos brevemente sobre la historia de lo que sucede cuando cargas una página web en un navegador (de lo que hablamos por primera vez en nuestro artículo Cómo funciona CSS). Cuando cargas una página web en tu navegador, estás ejecutando tu código (HTML, CSS y JavaScript) dentro de un entorno de ejecución (la pestaña del navegador). Esto es como una fábrica que toma materias primas (el código) y genera un producto (la página web).

+ +

+ +

Un uso muy común de JavaScript es modificar dinámicamente HTML y CSS para actualizar una interfaz de usuario, a través de la API del modelo de objetos del documento (como se mencionó anteriormente). Ten en cuenta que el código de tus documentos web generalmente se cargan y ejecutan en el orden en que aparece en la página. Si JavaScript se carga e intenta ejecutarse antes de que se hayan cargado el HTML y el CSS al que afecta, pueden producirse errores. Aprenderás formas de evitar esto más adelante en el artículo, en la sección Estrategias de carga de scripts.

+ +

Seguridad del navegador

+ +

Cada pestaña del navegador tiene su propio depósito separado para ejecutar código (estos depósitos se denominan "entornos de ejecución" en términos técnicos) — esto significa que, en la mayoría de los casos, el código de cada pestaña se ejecuta de forma completamente independiente y el código de una pestaña no puede afectar el código en otra pestaña, o en otro sitio web. Esta es una buena medida de seguridad — si este no fuera el caso, los piratas podrían comenzar a escribir código para robar información de otros sitios web y otras cosas muy malas.

+ +
+

Nota: Existen formas de enviar código y datos entre diferentes sitios web/pestañas de manera segura, pero estas son técnicas avanzadas que no cubriremos en este curso.

+
+ +

Orden de ejecución de JavaScript

+ +

Cuando el navegador encuentra un bloque de JavaScript, generalmente lo ejecuta en orden, de arriba a abajo. Esto significa que debes tener cuidado con el orden en el que colocas las cosas. Por ejemplo, volvamos al bloque de JavaScript que vimos en nuestro primer ejemplo:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+  let name = prompt('Enter a new name');
+  para.textContent = 'Player 1: ' + name;
+}
+ +

Aquí seleccionamos un párrafo de texto (línea 1), luego adjuntamos un detector de eventos (línea 3) de modo que cuando se hace clic en el párrafo, el bloque de código updateName() (líneas 5-8) se ejecuta. El bloque de código updateName() (estos tipos de bloques de código reutilizables se denominan "funciones") pide al usuario un nuevo nombre y luego inserta ese nombre en el párrafo para actualizar la pantalla.

+ +

Si cambiaras el orden de las dos primeras líneas de código, ya no funcionaría — en su lugar, obtendrías un error en la consola del desarrollador del navegadorTypeError: para is undefined. Esto significa que el objeto para aún no existe, por lo que no podemos agregarle un detector de eventos.

+ +
+

Nota: Este es un error muy común; debes tener cuidado de que los objetos a los que se hace referencia en tu código existan antes de intentar hacer algo con ellos.

+
+ +

Código interpretado versus compilado

+ +

Es posible que escuches los términos interpretados y compilados en el contexto de la programación. En los lenguajes interpretados, el código se ejecuta de arriba a abajo y el resultado de ejecutar el código se devuelve inmediatamente. No tienes que transformar el código en una forma diferente antes de que el navegador lo ejecute. El código se recibe en su forma de texto amigable para el programador y se procesa directamente desde allí.

+ +

Los lenguajes compilados, por otro lado, se transforman (compilan) a código máquina antes de que sean ejecutados por la computadora. Por ejemplo, C/C++ se compila a código máquina que luego ejecuta la computadora. El programa se ejecuta desde un formato binario, que se generó a partir del código fuente del programa original.

+ +

JavaScript es un lenguaje de programación interpretado ligero. El navegador web recibe el código JavaScript en su forma de texto original y ejecuta el script a partir de ahí. Desde un punto de vista técnico, la mayoría de los intérpretes de JavaScript modernos utilizan una técnica llamada compilación en tiempo real para mejorar el rendimiento; el código fuente de JavaScript se compila en un formato binario más rápido mientras se usa el script, de modo que se pueda ejecutar lo más rápido posible. Sin embargo, JavaScript todavía se considera un lenguaje interpretado, ya que la compilación se maneja en el entorno de ejecución, en lugar de antes.

+ +

Ambos tipos de lenguaje tienen ventajas, pero no las abordaremos ahora.

+ +

Código de lado del servidor versus de lado del cliente

+ +

También puedes escuchar los términos código de lado del servidor y de lado del cliente, especialmente en el contexto del desarrollo web. El código de lado del cliente es un código que se ejecuta en la computadora del usuario — cuando se ve una página web, el código de lado del cliente de la página se descarga, luego se ejecuta y se muestra en el navegador. En este módulo estamos hablando explícitamente de JavaScript de lado del cliente.

+ +

El código de lado del servidor, por otro lado, se ejecuta en el servidor, luego sus resultados se descargan y se muestran en el navegador. Ejemplos de lenguajes web populares de lado del servidor incluyen a ¡PHP, Python, Ruby, ASP.NET y... JavaScript! JavaScript también se puede utilizar como lenguaje de lado del servidor, por ejemplo, en el popular entorno Node.js — puedes obtener más información sobre JavaScript de lado del servidor en nuestro tema Sitios web dinámicos — Programación de lado del servidor.

+ +

Código dinámico versus estático

+ +

La palabra dinámico se usa para describir tanto a JavaScript de lado del cliente como a los lenguajes de lado del servidor — se refiere a la capacidad de actualizar la visualización de una página web/aplicación para mostrar diferentes cosas en diferentes circunstancias, generando contenido nuevo según sea necesario. El código de lado del servidor genera dinámicamente nuevo contenido en el servidor, p. ej. extraer datos de una base de datos, mientras que JavaScript de lado del cliente genera dinámicamente nuevo contenido dentro del navegador del cliente, p. ej. creando una nueva tabla HTML, llenándola con los datos solicitados al servidor y luego mostrando la tabla en una página web que se muestra al usuario. El significado es ligeramente diferente en los dos contextos, pero relacionado, y ambos enfoques (de lado del servidor y de lado del cliente) generalmente funcionan juntos.

+ +

Una página web sin contenido que se actualiza dinámicamente se denomina estática — simplemente muestra el mismo contenido todo el tiempo.

+ +

¿Cómo agregas JavaScript a tu página?

+ +

JavaScript se aplica a tu página HTML de manera similar a CSS. Mientras que CSS usa elementos {{htmlelement("link")}} para aplicar hojas de estilo externas y elementos {{htmlelement("style")}} para aplicar hojas de estilo internas a HTML, JavaScript solo necesita un amigo en el mundo de HTML: el elemento {htmlelement("script")}}. Aprendamos cómo funciona esto.

+ +

JavaScript interno

+ +
    +
  1. En primer lugar, haz una copia local de nuestro archivo de ejemplo apply-javascript.html. Guárdalo en un directorio en algún lugar accesible.
  2. +
  3. Abre el archivo en tu navegador web y en tu editor de texto. Verás que el HTML crea una página web simple que contiene un botón en el que se puede hacer clic.
  4. +
  5. A continuación, ve a tu editor de texto y agrega lo siguiente en tu head, justo antes de tu etiqueta de cierre </head>: +
    <script>
    +
    +  // JavaScript va aquí
    +
    +</script>
    +
  6. +
  7. Ahora agregaremos algo de JavaScript dentro de nuestro elemento {{htmlelement("script")}} para que la página haga algo más interesante — agrega el siguiente código justo debajo de la línea "// El código JavaScript va aquí": +
    document.addEventListener("DOMContentLoaded", function() {
    +  function createParagraph() {
    +    let para = document.createElement('p');
    +    para.textContent = 'You clicked the button!';
    +    document.body.appendChild(para);
    +  }
    +
    +  const buttons = document.querySelectorAll('button');
    +
    +  for(let i = 0; i < buttons.length ; i++) {
    +    buttons[i].addEventListener('click', createParagraph);
    +  }
    +});
    +
  8. +
  9. Guarda tu archivo y actualiza el navegador — ahora deberías ver que cuando haces clic en el botón, se genera un nuevo párrafo y se coloca debajo.
  10. +
+ +
+

Nota: Si tu ejemplo no parece funcionar, sigue los pasos nuevamente y verifica que hiciste todo bien. ¿Guardaste tu copia local del código de inicio como un archivo .html? ¿Agregaste tu elemento {{htmlelement("script")}} justo antes de la etiqueta </head>? ¿Ingresaste el JavaScript exactamente como se muestra? JavaScript distingue entre mayúsculas y minúsculas y es muy exigente, por lo que debes ingresar la sintaxis exactamente como se muestra; de lo contrario, es posible que no funcione.

+
+ +
+

Nota: Puedes ver esta versión en GitHub como apply-javascript-internal.html o (verla en vivo también).

+
+ +

JavaScript externo

+ +

Esto funciona muy bien, pero ¿y si quisiéramos poner nuestro JavaScript en un archivo externo? Exploremos esto ahora.

+ +
    +
  1. Primero, crea un nuevo archivo en el mismo directorio que tu archivo HTML del ejemplo. Como nombre ponle script.js; asegúrate de que el nombre tenga la extensión .js, ya que así es como se reconoce como JavaScript.
  2. +
  3. Reemplaza tu elemento {{htmlelement("script")}} actual con lo siguiente: +
    <script src="script.js" defer></script>
    +
  4. +
  5. Dentro de script.js, agrega el siguiente script: +
    function createParagraph() {
    +  let para = document.createElement('p');
    +  para.textContent = 'You clicked the button!';
    +  document.body.appendChild(para);
    +}
    +
    +const buttons = document.querySelectorAll('button');
    +
    +for(let i = 0; i < buttons.length ; i++) {
    +  buttons[i].addEventListener('click', createParagraph);
    +}
    +
  6. +
  7. Guarda y actualiza tu navegador, ¡y deberías ver lo mismo! Funciona igual, pero ahora tenemos nuestro JavaScript en un archivo externo. Por lo general, esto es bueno en términos de organización de tu código y para hacerlo reutilizable en varios archivos HTML. Además, el HTML es más fácil de leer sin grandes trozos de script en él.
  8. +
+ +
+

Nota: Puedes ver esta versión en GitHub como apply-javascript-external.html y script.js (verla en vivo también).

+
+ +

Controladores de JavaScript en línea

+ +

Ten en cuenta que a veces te encontrarás con fragmentos de código JavaScript real dentro de HTML. Podría verse algo similar a esto:

+ +
+
function createParagraph() {
+  let para = document.createElement('p');
+  para.textContent = 'You clicked the button!';
+  document.body.appendChild(para);
+}
+ +
<button onclick="createParagraph()">Click me!</button>
+
+ +

Puedes probar esta versión de nuestra demostración a continuación.

+ +

{{ EmbedLiveSample('inline_js_example', '100%', 150, "", "", "hide-codepen-jsfiddle") }}

+ +

Esta demostración tiene exactamente la misma funcionalidad que en las dos secciones anteriores, excepto que el elemento {{htmlelement("button")}} incluye un controlador onclick en línea para que la función se ejecute cuando se presiona el botón .

+ +

Sin embargo, no hagas esto. Es una mala práctica contaminar tu HTML con JavaScript, y es ineficiente; tendrías que incluir el atributo onclick="createParagraph()" en cada botón al que desees que se aplique JavaScript.

+ +

El uso de una construcción de JavaScript pura te permite seleccionar todos los botones usando una instrucción. El código que usamos anteriormente para cumplir este propósito se ve así:

+ +
const buttons = document.querySelectorAll('button');
+
+for(let i = 0; i < buttons.length ; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +

Esto puede ser un poco más largo que el atributo onclick, pero funcionará para todos los botones, sin importar cuántos haya en la página, ni cuántos se agreguen o eliminen. No es necesario cambiar el JavaScript.

+ +
+

Nota: Intenta editar tu versión de apply-javascript.html y agrega algunos botones más en el archivo. Cuando la vuelvas a cargar, deberías encontrar que todos los botones al hacer clic crearán un párrafo. Limpio, ¿eh?

+
+ +

Estrategias para la carga de scripts

+ +

Hay una serie de problemas relacionados con la carga de los scripts en el momento adecuado. ¡Nada es tan simple como parece! Un problema común es que todo el HTML de una página se carga en el orden en que aparece. Si estás utilizando JavaScript para manipular elementos en la página (o exactamente, el Modelo de objetos del documento), tu código no funcionará si el JavaScript se carga y procesa antes que el HTML que estás intentando haga algo.

+ +

En los ejemplos de código anteriores, en los ejemplos internos y externos, JavaScript se carga y se ejecuta en el encabezado del documento, antes de analizar el cuerpo HTML. Esto podría causar un error, por lo que hemos utilizado algunas construcciones para solucionarlo.

+ +

En el ejemplo interno, puedes ver esta estructura alrededor del código:

+ +
document.addEventListener("DOMContentLoaded", function() {
+  ...
+});
+ +

Este es un detector de eventos, que escucha el evento "DOMContentLoaded" del navegador, lo cual significa que el cuerpo HTML está completamente cargado y analizado. El JavaScript dentro de este bloque no se ejecutará hasta que se active ese evento, por lo que se evita el error (aprenderás sobre los eventos más adelante en el curso).

+ +

En el ejemplo externo, usamos una función de JavaScript más moderno para resolver el problema, el atributo defer, que le dice al navegador que continúe descargando el contenido HTML una vez que se ha alcanzado la etiqueta del elemento <script>.

+ +
<script src="script.js" defer></script>
+ +

En este caso, tanto el script como el HTML se cargarán simultáneamente y el código funcionará.

+ +
+

Nota: En el caso externo, no necesitamos usar el evento DOMContentLoaded porque el atributo defer nos resolvió el problema. No usamos la solución defer para el ejemplo interno de JavaScript porque defer solo funciona para scripts externos.

+
+ +

Una solución pasada de moda a este problema solía ser colocar tu elemento script justo en la parte inferior del cuerpo (por ejemplo, justo antes de la etiqueta </body>), para que se cargara después de haber procesado todo el HTML. El problema con esta solución es que la carga/procesamiento del script está completamente bloqueado hasta que se haya cargado el DOM HTML. En sitios muy grandes con mucho JavaScript, esto puede causar un importante problema de rendimiento y ralentizar tu sitio.

+ +

async y defer

+ +

En realidad, hay dos modernas características que podemos usar para evitar el problema del bloqueo de script: async y defer (que vimos anteriormente). Veamos la diferencia entre estas dos.

+ +

Los scripts cargados con el atributo async (ve más abajo) descargarán el script sin bloquear el renderizado de la página y lo ejecutará tan pronto como el script se termine de descargar. No tienes garantía de que los scripts se ejecuten en un orden específico, solo que no detendrán la visualización del resto de la página. Es mejor usar async cuando los scripts de la página se ejecutan de forma independiente y no dependen de ningún otro script de la página.

+ +

Por ejemplo, si tienes los siguientes elementos script:

+ +
<script async src="js/vendor/jquery.js"></script>
+
+<script async src="js/script2.js"></script>
+
+<script async src="js/script3.js"></script>
+ +

No puedes confiar en el orden en que se cargarán los scripts. jquery.js se puede cargar antes o después de script2.js y script3.js y si este es el caso, cualquier función en esos scripts dependiendo de jquery producirá un error porque jquery no se definirá en el momento en que se ejecute el script.

+ +

async se debe usar cuando tienes un montón de scripts en segundo plano para cargar, y solo deseas ponerlos en su lugar lo antes posible. Por ejemplo, tal vez tengas algunos archivos de datos del juego para cargar, que serán necesarios cuando el juego realmente comience, pero por ahora solo deseas continuar mostrando la introducción del juego, los títulos y el lobby, sin que se bloqueen al cargar el script.

+ +

Los scripts cargados con el atributo defer (ve a continuación) se ejecutarán en el orden en que aparecen en la página y los ejecutará tan pronto como se descarguen el script y el contenido:

+ +
<script defer src="js/vendor/jquery.js"></script>
+
+<script defer src="js/script2.js"></script>
+
+<script defer src="js/script3.js"></script>
+ +

Todos los scripts con el atributo defer se cargarán en el orden en que aparecen en la página. Entonces, en el segundo ejemplo, podemos estar seguros de que jquery.js se cargará antes que script2.js y script3.js y que script2.js se cargará antes de script3.js. No se ejecutarán hasta que se haya cargado todo el contenido de la página, lo cual es útil si tus scripts dependen de que el DOM esté en su lugar (por ejemplo, modifican uno o más elementos de la página).

+ +

Para resumir:

+ + + +

Comentarios

+ +

Al igual que con HTML y CSS, es posible escribir comentarios en tu código JavaScript que el navegador ignorará y que existen simplemente para proporcionar instrucciones a tus compañeros desarrolladores sobre cómo funciona el código (y a ti, si regresas a tu código después de seis meses y no puedes recordar lo que hiciste). Los comentarios son muy útiles y deberías utilizarlos con frecuencia, especialmente para aplicaciones grandes. Hay dos tipos:

+ + + +

Entonces, por ejemplo, podríamos anotar el JavaScript de nuestra última demostración con comentarios como este:

+ +
// Función: crea un nuevo párrafo y lo agrega al final del cuerpo HTML.
+
+function createParagraph() {
+  let para = document.createElement('p');
+  para.textContent = 'You clicked the button!';
+  document.body.appendChild(para);
+}
+
+/*
+  1. Obtiene referencias de todos los botones de la página en un formato de arreglo.
+  2. Recorre todos los botones y agrega un detector de eventos 'click' a cada uno.
+
+  Cuando se presione cualquier botón, se ejecutará la función createParagraph().
+*/
+
+const buttons = document.querySelectorAll('button');
+
+for (let i = 0; i < buttons.length ; i++) {
+  buttons[i].addEventListener('click', createParagraph);
+}
+ +
+

Nota: En general, más comentarios suelen ser mejor que menos, pero debes tener cuidado si agregas muchos comentarios para explicar qué son las variables (los nombres de tus variables tal vez deberían ser más intuitivos), o para explicar operaciones muy simples (tal vez tu código sea demasiado complicado).

+
+ +

Resumen

+ +

Así que ahí tienes, tu primer paso en el mundo de JavaScript. Comenzamos solo con teoría, para comenzar a acostumbrarte a por qué usarías JavaScript y qué tipo de cosas puedes hacer con él. En el camino, viste algunos ejemplos de código y aprendiste cómo encaja JavaScript con el resto del código en tu sitio web, entre otras cosas.

+ +

JavaScript puede parecer un poco abrumador en este momento, pero no te preocupes — en este curso, te guiaremos en pasos simples que tendrán sentido en el futuro. En el próximo artículo, nos sumergiremos directamente en lo práctico, lo que te permitirá comenzar directamente y crear tus propios ejemplos de JavaScript.

+ + + +

{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}

+ +

En este modulo

+ + diff --git a/files/es/learn/javascript/first_steps/strings/index.html b/files/es/learn/javascript/first_steps/strings/index.html new file mode 100644 index 0000000000..e86560ae54 --- /dev/null +++ b/files/es/learn/javascript/first_steps/strings/index.html @@ -0,0 +1,299 @@ +--- +title: Manejar texto — cadenas en JavaScript +slug: Learn/JavaScript/First_steps/Strings +tags: + - Artículo + - Cadenas + - Comillas + - Guía + - JavaScript + - Novato + - Principiante + - Union + - Unir + - concatenación + - 'l10n:priority' + - strings +translation_of: Learn/JavaScript/First_steps/Strings +--- +

{{LearnSidebar}}

+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}
+ +

A continuación, centraremos nuestra atención en las cadenas de caracteres (strings): así es como se llaman los fragmentos de texto en programación. En este artículo veremos todas las cosas comunes que realmente deberías saber sobre cadenas de caracteres al aprender JavaScript, como crear cadenas, comillas en cadenas y unir cadenas.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de informática, una comprensión básica de HTML y CSS y de lo que es JavaScript.
Objectivo:Familiarizarte con los aspectos básicos de las cadenas de caracteres en JavaScript.
+ +

El poder de las palabras

+ +

Las palabras son muy importantes para los humanos — son una parte fundamental de nuestra comunicación. Dado que la Web es un medio en gran parte basado en texto diseñado para permitir a los humanos comunicarse y compartir información, es útil para nosotros tener control sobre las palabras que aparecen en él. {{glossary("HTML")}} proporciona estructura y significado a nuestro texto, {{glossary("CSS")}} nos permite personalizarlo con precisión, y JavaScript contiene una serie de funciones para manipular cadenas, crear mensajes personalizados de bienvenida, mostrar las etiquetas de texto adecuadas cuando sea necesario, organizar los términos en el orden deseado y mucho más.

+ +

Casi todos los programas que hemos mostrado hasta ahora en el curso han involucrado alguna manipulación de cadenas.

+ +

Cadenas — las bases

+ +

A primera vista, las cadenas se tratan de forma similar a los números, pero cuando profundizas empiezas a ver diferencias notables. Comencemos ingresando algunas líneas de texto básicas en la consola para familiarizarnos. Te proveeremos de una aquí abajo (también puedes abrir la consola en una pestaña o ventana separada, o usar la consola de desarrollo del navegador si así lo prefieres).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Creando una cadena

+ +
    +
  1. Para comenzar, ingresa las siguientes líneas: +
    var string = 'La revolución no será televisada.';
    +string;
    + Al igual que con los números, declaramos una variable, iniciandola con el valor de una cadena, y luego retornamos dicho valor. La única diferencia es que al escribir una cadena, necesitas envolverla con comillas.
  2. +
  3. Si no lo haces, u olvidas una de las comillas, obtendrás un error. Intenta ingresando las siguientes líneas: +
    var malString = Esto es una prueba;
    +var malString = 'Esto es una prueba;
    +var malString = Esto es una prueba';
    + Estas líneas no funcionan porque el texto sin comillas alrededor es tomado como nombre de una variable, propiedad, palabra reservada, o algo similar. Si el navegador no las encuentra, entonces se recibe un error( ej. "missing ; before statement"). Si el navegador puede ver dónde comienza una cadena, pero no dónde termine, como se indica en la segunda oración, devuelve error (con "unterminated string literal"). Si tu programa devuelve estos errores, revisa desde el inicio que todas tus cadenas posean sus comillas.
  4. +
  5. Lo siguiente funcionará si previamente definiste la variable string — inténtalo: +
    var maltring = string;
    +malString;
    + malString ahora tiene el mismo valor que string.
  6. +
+ +

Comillas simples vs. comillas dobles

+ +
    +
  1. En JavaScript, puedes escoger entre comillas simple y dobles para envolver tus cadenas. Ambas funcionarán correctamente: +
    var simp = 'Comillas simples.';
    +var dobl = "Comillas dobles.";
    +simp;
    +dobl;
    +
  2. +
  3. Hay muy poca diferencia entre las dos, y la que utilices dependerá de tus preferencias personales. Sin embargo, deberías de elegir una y mantenerla; usar diferentes tipos de comillas en el código podría llegar a ser confuso, especialmente si utilizas diferentes comillas en la misma cadena. El siguiente ejemplo devolverá un error: +
    var badQuotes = 'What on earth?";
    +
  4. +
  5. El navegador pensará que la cadena no se ha cerrado correctamente, porque el otro tipo de cita que no estás usando, puede aparecer en la cadena. Por ejemplo, en estos dos casos su uso es correcto: +
    var sglDbl = 'Would you eat a "fish supper"?';
    +var dblSgl = "I'm feeling blue.";
    +sglDbl;
    +dblSgl;
    +
  6. +
  7. Sin embargo, no puedes usar el mismo tipo de comillas en el interior de una cadena que ya las tiene en los extremos. Lo siguiente devuelve error, porque confunde al navegador respecto de dónde termina la cadena: +
    var bigmouth = 'I've got no right to take my place...';
    + Lo que nos lleva directamente al siguiente tema.
  8. +
+ +

Escapando caracteres en una cadena

+ +

Para solucionar nuestro problema anterior, necesitamos "escapar" el asunto de las comillas. Escapar caracteres significa que les hacemos algo para asegurarnos que sean reconocidos como texto, y no parte del código. En JavaScript, colocamos una barra invertida justo antes del caracter. Intenta ésto:

+ +
var bigmouth = 'I\'ve got no right to take my place...';
+bigmouth;
+ +

Ahora funciona correctamente. Puedes escapar otros caracteres de la misma forma, ej. \", y hay varios códigos más. Ve a Notación de Escape para más detalles.

+ +

Concatenando cadenas

+ +
    +
  1. Concatenar es una elegante palabra de la programación que significa: "unir". Para unir cadenas en JavaScript el símbolo de más (+), el mismo operador que usamos para sumar números, pero en este contexto hace algo diferente. Vamos a probar un ejemplo en nuestra consola. +
    var one = 'Hello, ';
    +var two = 'how are you?';
    +var joined = one + two;
    +joined;
    + El resultado de este código es una variable llamada joined, que contiene el valor: "Hello, how are you?" ("Hola, cómo estas?").
  2. +
  3. En la última instancia del código, unimos dos strings, pero lo puedes hacer con cuantas desees, mientras que incluyas el símbolo de + entre ellas. Prueba esto: +
    var multiple = one + one + one + one + two;
    +multiple;
    +
  4. +
  5. También puedes usar una combinación de variables y strings reales. Prueba esto: +
    var response = one + 'I am fine — ' + two;
    +response;
    +
  6. +
+ +
+

Nota: Cuando ingresas una string real en tu código, entre comillas simples o dobles, se llama string literal.

+
+ +

La concatenación en contexto

+ +

Vamos a revisar la concatenación que usamos en la siguiente acción — veamos este ejemplo ya citado previamente en el curso:

+ +
<button>Press me</button>
+ +
var button = document.querySelector('button');
+
+button.onclick = function() {
+  var name = prompt('What is your name?');
+  alert('Hello ' + name + ', nice to see you!');
+}
+ +

{{ EmbedLiveSample('Concatenation_in_context', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

Aquí estamos usando una función {{domxref("Window.prompt()", "Window.prompt()")}} en la línea 4, que le pide al usuario la respuesta a una pregunta, através de un cuadro emergente (también llamado popup) y luego, almacenará el dato dentro de una variable dada — en este caso llamada name (nombre). Luego, en la línea 5, usamos una función {{domxref("Window.alert()", "Window.alert()")}} para mostrar otra ventana emergente que contiene una cadena que hemos unido de la concatenación de dos string literales y la variable name (nombre). 

+ +

Números versus cadenas

+ +
    +
  1. Entonces, ¿qué sucede cuando intentamos agregar (o concatenar) un string y un número? Vamos a probar en la consola: +
    'Front ' + 242;
    +
    + Podrías esperar que diera un error, pero funciona a la perfección. Tratar de representar un string como un número no tiene sentido, pero representar un número como string si que lo tiene, así que el navegador convierte el número en una string y las muestra juntas. 
  2. +
  3. Incluso puedes hacer esto con dos números — puedes forar un número para que se convierta en una string envolviéndolo entre comillas. Prueba lo siguiente (estamos utilizando el operador typeof para verificar si la variable es un número o una cadena): +
    var myDate = '19' + '67';
    +typeof myDate;
    +
  4. +
  5. Si tienes una variable numérica, que deseas convertir en una string, pero no cambiar de otra forma, o una variable string, que deseas convertir a número, pero no cambiarla de otra forma, puedes usar las siguientes construcciones: +
      +
    • El objecto {{jsxref("Number")}} convertirá cualquier cosa que se le pase en un número, si puede. Intenta lo siguiente: +
      var myString = '123';
      +var myNum = Number(myString);
      +typeof myNum;
      +
    • +
    • Por otra parte, cada número tiene un método llamado  toString() que convertirá el equivalente en una string. Prueba esto: +
      var myNum = 123;
      +var myString = myNum.toString();
      +typeof myString;
      +
    • +
    + Estas construcciones pueden ser muy útiles en ciertas situaciones. Por ejemplo, si un usuario introduce un número en un campo de texto de un formulario, será un string. Sin embargo, si quieres añadir ese número a algo, lo necesitas convertir a número, así que puedes usar esta construcción para hacerlo. Hicimos exactamente esto en el ejercicio de ejemplo: Juego adivina el número en la línea 54 (Juego Adivina el número, en la línea 54).
  6. +
+ +

Prueba tus habilidades

+ +

Llegaste al final de este artículo, pero ¿puédes recordar la información más importante? Puedes encontrar algunas pruebas para verificar que has comprendido esta información antes de seguir avanzando — Ve Prueba tus habilidades: Strings. Ten en cuenta que esto requiere conocimiento del próximo artículo, por lo que podrías leerlo antes.

+ +

Conclusión

+ +

Esto es lo básico que debes saber sobre las cadenas o strings en JavaScript. En el siguiente artículo desarrollaremos más sobre esto, observando métodos de construcción de strings disponibles en JavaScript y cómo podemos usarlos para manipular nuestras cadenas de la forma que queremos. 

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/test_your_skills_colon__math/index.html b/files/es/learn/javascript/first_steps/test_your_skills_colon__math/index.html new file mode 100644 index 0000000000..e02f502bce --- /dev/null +++ b/files/es/learn/javascript/first_steps/test_your_skills_colon__math/index.html @@ -0,0 +1,91 @@ +--- +title: 'Comprueba tus habilidades: Matematicas.' +slug: 'Learn/JavaScript/First_steps/Test_your_skills:_Math' +tags: + - JavaScript + - Matemática + - Principiante + - Prueba tus habilidades + - aprende +translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_Math' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba de habilidad es conocer si has entendido nuestra clase sobre el articulo Matematica basica en JavaScript — números y operadores.

+ +
+

Nota: Puedes probar soluciones en los editores interactivos a continuación, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePen, jsFiddle, o Glitch para trabajar en las tareas.

+ +

Si se queda atascado, pídanos ayuda; consulte la sección {{anch ("Evaluación o ayuda adicional")}} en la parte inferior de esta página.

+ +

Nota: En los ejemplos a continuación, si hay un error en su código, se mostrará en el panel de resultados de la página, para ayudarlo a tratar de averiguar la respuesta (o en la consola JavaScript del navegador, en el caso de la versión descargable).

+
+ +

Math 1

+ +

Iniciemos poniendo a prueba sus conocimientos acerca de los operadores matemáticos básicos. Usted tendrá que crear 4 valores númericos, unir los 2 primeros, hacer una resta del cuarto con el tercero y multiplicar los resultados secundarios juntos para obtener un resultado final de 48. Y finalmente, necesita ejecutar una prueba para comprobar si el resultado es un numero par.

+ +

Asi que intente realizar la actualización del código descrito abajo para crear el ejemplo terminado, siguendo estos pasos:

+ +
    +
  1. Crea cuatro variables que contengan numeros. Llama a las variables razonablemente.
  2. +
  3. Agrega las dos primeras variables juntas y guarda el resultado en otra variable.
  4. +
  5. Subtract the fourth variable from the third and store the result in another variable.
  6. +
  7. Multiply the results from the last two steps together, storing the result in a variable called finalResult. The product should be 48. If it isn't, you'll have to adjust some of the initial input values.
  8. +
  9. Finally, write a calculation that checks whether finalResult is an even number. Store the result in a variable called evenOddResult.
  10. +
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/math/math1.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Math 2

+ +

In the second task you are already provided with two calculations, with the results stored in the variables result and result2. But these results aren't what we want; you'll need to take the calculations and change them to give us what we want.

+ +

What do we want? After multiplying the two results together and formatting the result to 2 decimal places, the final result should be 10.42.

+ +

Try updating the live code below to recreate the finished example, following these steps:

+ +
    +
  1. Write a calculation that multiples result and result2 together and assigns the result back to result. This will require assignment shorthand.
  2. +
  3. Write a line of code that takes result and formats it to 2 decimal places, storing the result of this in a variable called finalResult.
  4. +
  5. Check the data type of finalResult using typeof; you'll probably see that it is actually of string type! Write a line of code that converts it to a number type, storing the result in a variable called finalNumber.
  6. +
  7. The value of finalNumber needs to be 10.42. Go back and update the original calculations you were provided with so that they give this final result. Don't update the numbers or the operators.
  8. +
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/math/math2.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Math 3

+ +

In the final task for this article, we want you to write some tests. You've got three groups, each consisting of a statement and two variables. For each one, write a test that proves or disproves the statement made. Store the results of those tests in variables called weightComparison, heightComparison, and pwdMatch, respectively.

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/math/math3.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

Assessment or further help

+ +

You can practice these examples in the Interactive Editors above.

+ +

If you would like your work assessed, or are stuck and want to ask for help:

+ +
    +
  1. Put your work into an online shareable editor such as CodePen, jsFiddle, or Glitch. You can write the code yourself, or use the starting point files linked to in the above sections.
  2. +
  3. Write a post asking for assessment and/or help at the MDN Discourse forum Learning category. Your post should include: +
      +
    • A descriptive title such as "Assessment wanted for Math 1 skill test".
    • +
    • Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.
    • +
    • A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.
    • +
    • A link to the actual task or assessment page, so we can find the question you want help with.
    • +
    +
  4. +
diff --git a/files/es/learn/javascript/first_steps/test_your_skills_colon__variables/index.html b/files/es/learn/javascript/first_steps/test_your_skills_colon__variables/index.html new file mode 100644 index 0000000000..c242ff5ccc --- /dev/null +++ b/files/es/learn/javascript/first_steps/test_your_skills_colon__variables/index.html @@ -0,0 +1,84 @@ +--- +title: '¡Pon a prueba tus habilidades!: Variables' +slug: 'Learn/JavaScript/First_steps/Test_your_skills:_variables' +tags: + - JavaScript + - Principiante + - Tus habilidades con texto + - Variables + - aprende +translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_variables' +--- +
{{learnsidebar}}
+ +

El objetivo de esta prueba de habilidad es evaluar si has entendido nuestro artículo Almacenando la información que necesitas — Variables.

+ +
+

Nota: Puedes probar las soluciones en los editores interactivos a continuación, sin embargo, puede ser útil descargar el código y usar una herramienta en línea como CodePen, jsFiddle, o Glitch para trabajar en las tareas.
+
+ Si te atascas, pídenos ayuda; consulta la sección {{anch('Evaluación o ayuda adicional')}} en la parte inferior de esta página.

+
+ +
+

Nota: En los siguientes ejemplos, si hay un error en tu código, se mostrará en el panel de resultados de la página, para ayudarte a intentar averiguar la respuesta (o en la consola JavaScript del navegador, en el caso de la versión descargable).

+
+ +

Variables 1

+ +

En esta tarea queremos que:

+ + + +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample('learning-area/javascript/introduction-to-js-1/tasks/variables/variables1.html', '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Variables 2

+ +

En esta tarea, debes agregar una nueva línea para corregir el valor almacenado en la variable myName existente a tu propio nombre.

+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample('learning-area/javascript/introduction-to-js-1/tasks/variables/variables2.html', '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Variables 3

+ +

La tarea final por ahora — en este caso, se te proporciona un código existente, que tiene dos errores presentes. El panel de resultados debería mostrar el nombre Chris y una declaración sobre la edad que tendrá Chris dentro de 20 años. ¿Cómo puedes solucionar el problema y corregir la salida?

+ +

Intenta actualizar el código en vivo a continuación para recrear el ejemplo terminado:

+ +

{{EmbedGHLiveSample('learning-area/javascript/introduction-to-js-1/tasks/variables/variables3.html', '100%', 400)}}

+ +
+

Descarga el punto de partida de esta tarea para trabajar en tu propio editor o en un editor en línea.

+
+ +

Evaluación o ayuda adicional

+ +

Puedes practicar estos ejemplos en los editores interactivos anteriores.

+ +

Si deseas que se evalúe tu trabajo o estás atascado y deseas pedir ayuda:

+ +
    +
  1. Coloca tu trabajo en un editor que se pueda compartir en línea, como CodePen, jsFiddle o Glitch. Puedes escribir el código tú mismo o utilizar los archivos de punto de partida vinculados en las secciones anteriores.
  2. +
  3. Escribe una publicación solicitando evaluación y/o ayuda en la categoría de aprendizaje del foro de discusión de MDN. Tu publicación debe incluir: +
      +
    • Un título descriptivo como Evaluación deseada para la prueba de habilidad de Variables 1.
    • +
    • Detalles de lo que ya has probado y lo que te gustaría que hiciéramos, p. ej. si estás atascado y necesitas ayuda, o quieres una evaluación.
    • +
    • Un enlace al ejemplo que deseas evaluar o con el que necesitas ayuda, en un editor que se pueda compartir en línea (como se mencionó en el paso 1 anterior). Esta es una buena práctica para empezar — es muy difícil ayudar a alguien con un problema de codificación si no puedes ver su código.
    • +
    • Un enlace a la página de la tarea o evaluación real, para que podamos encontrar la pregunta con la que deseas ayuda.
    • +
    +
  4. +
diff --git a/files/es/learn/javascript/first_steps/useful_string_methods/index.html b/files/es/learn/javascript/first_steps/useful_string_methods/index.html new file mode 100644 index 0000000000..09c6cfea08 --- /dev/null +++ b/files/es/learn/javascript/first_steps/useful_string_methods/index.html @@ -0,0 +1,718 @@ +--- +title: Métodos útiles con cadenas +slug: Learn/JavaScript/First_steps/Useful_string_methods +tags: + - Artículo + - Cadenas + - JavaScript + - Métodos + - Principiante +translation_of: Learn/JavaScript/First_steps/Useful_string_methods +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

Ahora que hemos analizado los conceptos básicos de las cadenas, aumentemos la velocidad y comencemos a pensar qué operaciones útiles podemos hacer en cadenas con métodos integados, como encontrar la longitud de una cadena de texto, unir y dividir cadenas, sustituyendo un caracter de una cadena por otro, y más.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de informática, una comprensión básica de HTML y CSS, una comprensión de lo que es JavaScript.
Objectivo:Comprender que las cadenas son objetos y aprender a usar algunos de los métodos básicos disponibles en esos objetos para manipular cadenas.
+ +

Cadenas como objetos

+ +

Ya lo dijimos antes, y lo diremos de nuevo — todo es un objeto en JavaScript. Cuando creas una cadena, por ejemplo, usando:

+ +
let string = 'This is my string';
+ +

Tu variable se convierte en una instancia del objeto cadena y, como resultado, tiene una gran cantidad de propiedades y métodos disponibles. Puedes ver esto si vas a la página de objeto {{jsxref("String")}} y miras la lista al costado de la página.

+ +

Ahora, antes de que tu cerebro comience a derretirse, ¡no te preocupes! Realmente no necesitas saber acerca de la mayoría de estos principios en tu viaje de aprendizaje. Pero hay algunos que posiblemente utilizarás con bastante frecuencia así como veremos aquí. 

+ +

Ingresemos algunos ejemplos en una nueva consola. A continuación, proporcionamos uno (también puedes abrir esta consola en una ventana o pestaña por separado, o si prefieres usar la consola de desarrolladores del navegador).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Encontrar la longitud de un cadena

+ +

Esto es fácil — simplemente usa la propiedad {{jsxref("String.prototype.length", "length")}} . Intenta ingresar las siguientes líneas:

+ +
let browserType = 'mozilla';
+browserType.length;
+ +

Esto debería devolver el número 7, porque "mozilla" tiene 7 caracteres. Esto es útil por muchas razones; por ejemplo, es posible que quieras buscar las longitudes de una serie de nombres para que puedas mostrarlos en orden de su longitud, o dejar que un usuario  sepa que un nombre ingresado en un campo de formulario es demasiado largo o si tiene una longitud determinada.

+ +

Extrayendo un específico caracter de la cadena

+ +

En una nota relacionada, puedes devolver cualquier carácter de una cadena usando la notación de corchetes — esto significa que incluyes corchetes ([]) al final del nombre de tu variable. Dentro de los corchetes, incluye el número del caracter que deseas extraer, así que, por ejemplo, para extraer la primera letra harías esto:

+ +
browserType[0];
+ +

¡ Las computadoras cuentan desde 0, no desde 1! Para extraer el último caracter de cualquier cadena, podríamos usar la siguiente línea, combinando esta técnica con la propiedad length que vimos arriba:

+ +
browserType[browserType.length-1];
+ +

El largo de "mozilla" es 7, pero es porque el contador comienza en 0, la posición del caracter es 6, por lo tanto, necesitamos length-1. Puedes usar esto para, por ejemplo, encontrar la primera letra de una serie de cadenas y ordenarlas alfabéticamente.

+ +

Encontrar una subcadena dentro de una cadena y extraerla

+ +
    +
  1. Algunas veces querrás encontrar si hay una cadena más pequeña dentro de una más grande (generalmente decimos si una subcadena está presente dentro de una cadena). Esto se puede hacer utilizando el método {{jsxref("String.prototype.indexOf()", "indexOf()")}}, que toma un único parámetro — la subcadena que deseas buscar. Intenta esto: + +
    browserType.indexOf('zilla');
    + Esto nos dá un resultado de 2, porque la subcadena "zilla" comienza en la posición 2 (0, 1, 2  — por tanto 3 caracteres en total) dentro de "mozilla". Tal código podría usarse para filtrar cadena. Por ejemplo, podemos tener una lista de direcciones web y solo queremos imprimir las que contienen "mozilla".
  2. +
+ +
    +
  1. Esto se puede hacer de otra manera, que posiblemente sea aún más efectiva. Intenta lo siguiente: +
    browserType.indexOf('vanilla');
    + Esto debería darte un resultado de -1 — Esto se devuelve cuando la subcadena, en este caso 'vanilla', no es encontrada en la cadena principal.
    +
    + Puedes usar esto para encontrar todas las instancias de las cadenas que no contengan la subcadena 'mozilla', o hacerlo, si usas el operador de negación, como se muestra a continuación. Podrías hacer algo como esto: + +
    if(browserType.indexOf('mozilla') !== -1) {
    +  // do stuff with the string
    +}
    +
  2. +
  3. Cuando sabes donde comienza una subcadena dentro de una cadena, y sabes hasta cuál caracter deseas que termine, puede usarse {{jsxref("String.prototype.slice()", "slice()")}} para extraerla. Prueba lo siguiente: +
    browserType.slice(0,3);
    + Esto devuelve "moz" — El primer parámetro es la posición del caracter en la que comenzar a extraer, y el segundo parámetro es la posición del caracter posterior al último a ser extraído. Por lo tanto, el corte ocurre desde la primera posición en adelante, pero excluyendo la última posición. En este ejemplo, dado que el índice inicial es 0, el segundo parámetro es igual a la longitud de la cadena que se devuelve.
    +  
  4. +
  5. Además, si sabes que deseas extraer todos los caracteres restantes de una cadena después de cierto caracter, ¡no necesitas incluir el segundo parámetro! En cambio, solo necesitas incluir la posición del caracter desde donde deseas extraer los caracteres restante en la cadena. Prueba lo siguiente: +
    browserType.slice(2);
    + Esto devuelve "zilla" — debido a que la posición del caracter de 2 es la letra z, y como no incluiste un segundo parámetro, la subcadena que que se devolvío fué el resto de los caracteres de la cadena. 
  6. +
+ +
+

Nota: El segundo parámetro de slice() es opcional: si no lo incluyes, el corte termina al final de la cadena original. Hay otras opciones también; estudia la página {{jsxref("String.prototype.slice()", "slice()")}} para ver que mas puedes averiguar.

+
+ +

Cambiando todo a mayúscula o minúscula

+ +

Los métodos de cadena {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}} y {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}} toman una cadena y convierten todos sus caracteres a mayúscula o minúscula, respectivamente. Esto puede ser útil, por ejemplo, si deseas normalizar todos los datos ingresados por el usuario antes de almacenarlos en una base de datos.

+ +

Intentemos ingresar las siguentes líneas para ver que sucede:

+ +
let radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();
+ +

Actualizando partes de una cadena

+ +

En una cadena puedes reemplazar una subcadena por otra usando el método {{jsxref("String.prototype.replace()", "replace()")}}. Esto funciona de manera muy simple a un nivel básico, aunque hay algunas cosas avanzadas que puedes hacer con él en lo que todavía no entraremos.

+ +

Toma dos parámetros — la cadena que deseas reemplazar, y la cadena con la que deseas reemplazarla. Prueba este ejemplo:

+ +
browserType.replace('moz','van');
+ +

Ten en cuenta que para obtener realmente el valor actualizado reflejado en la variable browserType en un programa real, debes establecer que el valor de la variable sea el resultado de la operación; No solo actualiza el valor de la subcadena automáticamente. Así que tendrías que escribir esto: browserType = browserType.replace('moz','van');

+ +

Ejemplos de aprendizaje activo

+ +

En esta sección, conseguiremos que intentes escribir algún código de manipulación de cadenas. En cada ejercicio a continuación, tenemos una matríz de cadenas y un bucle que procesa cada valor en la matríz y lo muestra en una lista con viñetas. No es necesario que comprendas matrices y bucles en este mismo momento — estos se explicarán en futuros artículos. Todo lo que necesitas hacer en cada caso es escribir el código que dará de salida a las cadenas en el formato que las queremos.

+ +

Cada ejemplo viene con un botón de "Reset" , Que puedes utilizar para reestablecer el código si cometes un error y no puedes hacerlo funcionar nuevamente, y un botón "Show solution" que puedes presionar para ver una posible respuesta si te encuentras realmente atorado.

+ +

Filtrado de mensajes de saludo

+ +

En el primer ejercicio, comenzamos de manera simple — tenemos una matríz de mensajes de tarjetas de felicitación, pero queremos ordenarlos para que aparezcan solo los mensajes de Navidad. Queremos que completes un test condicional dentro de la estructura if( ... ), para comprobar cada cadena y solo imprimirla en la lista si es un mensaje de Navidad.

+ +
    +
  1. Primero piensa en cómo puedes probar si el mensaje en cada caso es un mensaje de Navidad. ¿Qué cadena está presente en todos esos mensajes, y qué método podrías usar para comprobar si está presente?
  2. +
  3. A continuación, deberá escribir un test condicional de la forma operand1 operator operand2. ¿Es lo que está a la izquierda igual a lo que está a la derecha? O en este caso, ¿el método llamado a la izquierda devuelve el resultado a la derecha?
  4. +
  5. Sugerencia: En este caso, probablemente sea más útil comprobar si la llamada al método no es igual a un determinado resultado.
  6. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 590, "", "", "hide-codepen-jsfiddle") }}

+ +

Corrección de mayúscula

+ +

En este ejercicio tenemos los nombres de las ciudades del Reino Unido, Pero las mayúsculas estan completamente desordenadas. Queremos que los cambies para que estén en minúscula, a excepción de la primera letra. Una buena manera de hacerlo es:

+ +
    +
  1. Convierte la totalidad de la cadena contenida en la variable input a minúsculas y guárdalas en una nueva variable.
  2. +
  3. Toma la primera letra de la cadena en esta nueva variable y guárdala en otra variable.
  4. +
  5. Usando esta última variable como una subcadena, reemplaza la primera letra de la cadena en minúscula con la subcadena en mayúscula. Almacena el resultado de este procedimiento de reemplazo en otra nueva variable.
  6. +
  7. Cambia el valor de la variable result a igual al resultado final. en vez de input.
  8. +
+ +
+

Nota: Una pista — los parámetros de los métodos de cadena no tienen que ser literales de cadenas; también pueden ser variables, o incluso variables con un método invocados en ellas.

+
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 550, "", "", "hide-codepen-jsfiddle") }}

+ +

Creando nuevas cadenas de partes viejas

+ +

En este último ejercicio, la matríz contiene un conjunto de cadenas que contienen información sobre estaciones de tren en el Norte de Inglaterra. Las cadenas son elementos de datos que contienen el código de estación de tres letras, seguidos de más datos legibles por máquina, seguidos de un punto y coma, seguidos por el nombre de la estación legible por humanos. Por ejemplo:

+ +
MAN675847583748sjt567654;Manchester Piccadilly
+ +

Queremos extraer el código y el nombre de la estación, y juntarlos en una cadena con la siguiente estructura:

+ +
MAN: Manchester Piccadilly
+ +

Recomendamos hacerlo así:

+ +
    +
  1. Extrae las tres letras del código de estación y almacénalo en una nueva variable.
  2. +
  3. Encuentra el número de índice de caracter del punto y coma.
  4. +
  5. Extrae el nombre de la estación legible por humanos utilizando el número de índice de caracter del punto y coma a modo de referencia y guardalo en una nueva variable.
  6. +
  7. Concatenar las dos nuevas variables y un literal de cadena para hacer la cadena final.
  8. +
  9. Cambia el valor de la variable de result a igual a la cadena final, no a  input.
  10. +
+ + + +

{{ EmbedLiveSample('Playable_code_3', '100%', 585, "", "", "hide-codepen-jsfiddle") }}

+ +

Conclusión

+ +

No puedes negar el hecho de que ser capaz de manejar palablas y oraciones en la programación es muy importante — especialmente en JavaScript, ya que los sitios web tratan sobre la comunicación con las personas. Este artículo te ha proporcionado los conceptos básicos que necesitas saber sobre la manipulación de cadenas por ahora. Esto debería servirte bien a medida que abordas temas más complejos en el futuro. A continuación, vamos a ver el último tipo importante de datos en el que necesitamos enfocarnos en el corto plazo — matrices.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/variables/index.html b/files/es/learn/javascript/first_steps/variables/index.html new file mode 100644 index 0000000000..728ad187aa --- /dev/null +++ b/files/es/learn/javascript/first_steps/variables/index.html @@ -0,0 +1,340 @@ +--- +title: Almacenando la información que necesitas - Variables +slug: Learn/JavaScript/First_steps/Variables +tags: + - Arreglos + - Booleanos + - Booleans + - JavaScript + - Numeros + - Objetos + - Variables + - cadenas de texto + - 'l10n:priority' + - strings +translation_of: Learn/JavaScript/First_steps/Variables +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}
+ +

Después de leer los últimos artículos, deberías saber qué es JavaScript, qué puede hacer por ti, cómo usarlo junto con otras tecnologías web y cómo se ven sus características principales desde un alto nivel. En este artículo, llegaremos a los conceptos básicos reales, y veremos cómo trabajar con los bloques de construcción más básicos de JavaScript — Variables.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, comprensión básica de HTML y CSS, comprensión de lo que es JavaScript.
Objetivo:Familiarizarte con los conceptos básicos de las variables de JavaScript.
+ +

Herramientas que necesitas

+ +

A lo largo de este artículo, se te pedirá que escribas líneas de código para probar tu comprensión del contenido. Si estás utilizando un navegador de escritorio, el mejor lugar para escribir tu código de ejemplo es la consola JavaScript de tu navegador (consulta ¿Qué son las herramientas para el desarrollador del navegador? para obtener más información sobre cómo acceder a esta herramienta).

+ +

¿Qué es una variable?

+ +

Una variable es un contenedor para un valor, como un número que podríamos usar en una suma, o una cadena que podríamos usar como parte de una oración. Pero una cosa especial acerca de las variables es que los valores que contienen pueden cambiar. Veamos un sencillo ejemplo:

+ +
<button>Presióname</button>
+ +
const button = document.querySelector('button');
+
+button.onclick = function() {
+  let name = prompt('¿Cuál es tu nombre?');
+  alert('¡Hola ' + name + ', encantado de verte!');
+}
+ +

{{ EmbedLiveSample('What_is_a_variable', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

En este ejemplo, al presionar el botón se ejecutan un par de líneas de código. La primera línea muestra un cuadro en la pantalla que pide al lector que ingrese su nombre y luego almacena el valor en una variable. La segunda línea muestra un mensaje de bienvenida que incluye su nombre, tomado del valor de la variable.

+ +

Para entender por qué esto es tan útil, pensemos en cómo escribiríamos este ejemplo sin usar una variable. Terminaría luciendo algo como esto:

+ +
let name = prompt('¿Cuál es tu nombre?');
+
+if (name === 'Adam') {
+  alert('¡Hola Adam, encantado de verte!');
+} else if (name === 'Alan') {
+  alert('¡Hola Alan, encantado de verte!');
+} else if (name === 'Bella') {
+  alert('¡Hola Bella, encantado de verte!');
+} else if (name === 'Bianca') {
+  alert('¡Hola Bianca, encantado de verte!');
+} else if (name === 'Chris') {
+  alert('¡Hola Chris, encantado de verte!');
+}
+
+// ... y así sucesivamente ...
+ +

Es posible que (¡todavía!) no comprendas completamente la sintaxis que estamos usando, Pero deberías poder hacerte una idea — si no tuviéramos variables disponibles, tendríamos que implementar un bloque de código gigante que verificara cuál era el nombre ingresado, y luego muestra el mensaje apropiado para cualquier nombre. Obviamente, esto realmente es ineficiente (el código es mucho más grande, incluso para solo cinco opciones), y simplemente no funcionaría — no podrías almacenar todas las opciones posibles.

+ +

Las variables simplemente tienen sentido y, a medida que aprendas más sobre JavaScript, comenzarán a convertirse en una segunda naturaleza.

+ +

Otra cosa especial acerca de las variables es que pueden contener casi cualquier cosa, no solo cadenas y números. Las variables también pueden contener datos complejos e incluso funciones completas para hacer cosas asombrosas. Aprenderás más sobre esto a medida que avances.

+ +
+

Nota: Decimos que las variables contienen valores. Ésta es una importante distinción que debemos reconocer. Las variables no son los valores en sí mismos; son contenedores de valores. Puedes pensar en ellas como pequeñas cajas de cartón en las que puedes guardar cosas.

+
+ +

+ +

Declarar una variable

+ +

Para usar una variable, primero debes crearla — precisamente, a esto lo llamamos declarar la variable. Para hacerlo, escribimos la palabra clave var o let seguida del nombre con el que deseas llamar a tu variable:

+ +
let myName;
+let myAge;
+ +

Aquí estamos creando dos variables llamadas myName y myAge. Intenta escribir estas líneas en la consola de tu navegador web. Después de eso, intenta crear una variable (o dos) eligiendo tú su nombre.

+ +
+

Nota: En JavaScript, todas las instrucciones en el código deben terminar con un punto y coma (;) — tu código puede funcionar correctamente para líneas individuales, pero probablemente no lo hará cuando estés escribiendo varias líneas de código juntas. Trata de adquirir el hábito de incluirlo.

+
+ +

Puedes probar si estos valores existen ahora en el entorno de ejecución escribiendo solo el nombre de la variable, p. ej.

+ +
myName;
+myAge;
+ +

Actualmente no tienen ningún valor; son contenedores vacíos. Cuando ingreses los nombres de las variables, deberías obtener devuelto un valor undefined. Si no existen, recibirás un mensaje de error; intenta escribir

+ +
scoobyDoo;
+ +
+

Nota: No confundas una variable que existe pero no tiene un valor definido, con una variable que no existe en absoluto — son cosas muy diferentes. En la analogía de cajas que viste arriba, no existir significaría que no hay una caja (variable) para guardar un valor. Ningún valor definido significaría que HAY una caja, pero no tiene ningún valor dentro de ella.

+
+ +

Iniciar una variable

+ +

Una vez que hayas declarado una variable, la puedes iniciar con un valor. Para ello, escribe el nombre de la variable, seguido de un signo igual (=), seguido del valor que deseas darle. Por ejemplo:

+ +
myName = 'Chris';
+myAge = 37;
+ +

Intenta volver a la consola ahora y escribe estas líneas. Deberías ver el valor que le has asignado a la variable devuelto en la consola para confirmarlo, en cada caso. Nuevamente, puedes devolver los valores de tus variables simplemente escribiendo su nombre en la consola; inténtalo nuevamente:

+ +
myName;
+myAge;
+ +

Puedes declarar e iniciar una variable al mismo tiempo, así:

+ +
let myDog = 'Rover';
+ +

Esto probablemente es lo que harás la mayor parte del tiempo, ya que es más rápido que realizar las dos acciones en dos líneas separadas.

+ +

Diferencia entre var y let

+ +

En este punto, puedes estar pensando "¿por qué necesitamos dos palabras clave para definir variables? ¿Por qué var y let?".

+ +

Las razones son algo históricas. Cuando se creó JavaScript por primera vez, solo existía var. Esto básicamente funciona bien en la mayoría de los casos, pero tiene algunos problemas en la forma en que trabaja — su diseño a veces puede ser confuso o francamente molesto. Entonces, se creó let en versiones modernas de JavaScript, una nueva palabra clave para crear variables que funciona de manera algo diferente a var, solucionando sus problemas en el proceso.

+ +

A continuación se explican un par de diferencias simples. No abordaremos todas las diferencias ahora, pero comenzarás a descubrirlas a medida que aprendas más sobre JavaScript (si realmente deseas leer sobre ellas ahora, no dudes en consultar {{jsxref("Sentencias/let", "let")}} en nuestra página de referencia.

+ +

Para empezar, si escribes un programa JavaScript de varias líneas que declara e inicia una variable, puedes declarar una variable con var después de iniciarla y seguirá funcionando. Por ejemplo:

+ +
myName = 'Chris';
+
+function logName() {
+  console.log(myName);
+}
+
+logName();
+
+var myName;
+ +
+

Nota: Esto no funcionará al escribir líneas individuales en una consola de JavaScript, solo cuando se ejecutan varias líneas de JavaScript en un documento web.

+
+ +

Esto funciona debido a la elevación — lee {{jsxref("Sentencias/var", "Elevación de variables", "#Elevación_de_variables")}} para obtener más detalles sobre el tema.

+ +

La elevación (hoisting) ya no funciona con let. Si cambiamos var a let en el ejemplo anterior, fallaría con un error. Esto es bueno — declarar una variable después de iniciarla resulta en un código confuso y más difícil de entender.

+ +

En segundo lugar, cuando usas var, puedes declarar la misma variable tantas veces como desees, pero con let no puedes. Lo siguiente funcionaría:

+ +
var myName = 'Chris';
+var myName = 'Bob';
+ +

Pero lo siguiente arrojaría un error en la segunda línea:

+ +
let myName = 'Chris';
+let myName = 'Bob';
+ +

Tendrías que hacer esto en su lugar:

+ +
let myName = 'Chris';
+myName = 'Bob';
+ +

Nuevamente, esta es una sensata decisión del lenguaje. No hay razón para volver a declarar las variables — solo hace que las cosas sean más confusas.

+ +

Por estas y otras razones, se recomienda utilizar let tanto como sea posible en tu código, en lugar de var. No hay ninguna razón para usar var, a menos que necesites admitir versiones antiguas de Internet Explorer con tu código (no es compatible con let hasta la versión 11; Edge el moderno navegador de Windows admite let perfectamente).

+ +

Actualizar una variable

+ +

Una vez que una variable se ha iniciado con un valor, puedes cambiar (o actualizar) ese valor simplemente dándole un valor diferente. Intenta ingresar las siguientes líneas en tu consola:

+ +
myName = 'Bob';
+myAge = 40;
+ +

Un consejo sobre las reglas de nomenclatura de variables

+ +

Puedes llamar a una variable prácticamente como quieras, pero existen limitaciones. En general, debes limitarte a usar caracteres latinos (0-9, a-z, A-Z) y el caracter de subrayado.

+ + + +
+

Nota: Puedes encontrar una lista bastante completa de palabras clave reservadas que debes evitar en {{jsxref("Gramática_léxica", "Gramática léxica — Palabras clave", "#Palabras_clave")}}.

+
+ +

Ejemplos de buenos nombres:

+ +
age
+myAge
+init
+initialColor
+finalOutputValue
+audio1
+audio2
+ +

Ejemplos de nombres incorrectos:

+ +
1
+a
+_12
+myage
+MYAGE
+var
+Document
+skjfndskjfnbdskjfb
+thisisareallylongstupidvariablenameman
+ +

Ahora, intenta crear algunas variables más, con la guía anterior en mente.

+ +

Tipo de las variables

+ +

Hay algunos tipos de datos diferentes que podemos almacenar en variables. En esta sección, los describiremos brevemente, luego, en artículos futuros, aprenderás más detalles.

+ +

Hasta ahora hemos analizado los dos primeros, pero hay otros.

+ +

Números

+ +

Puedes almacenar números en variables, ya sea números enteros como 30 (también llamados enteros — "integer") o números decimales como 2.456 (también llamados números flotantes o de coma flotante — "number"). No es necesario declarar el tipo de las variables en JavaScript, a diferencia de otros lenguajes de programación. Cuando le das a una variable un valor numérico, no incluye comillas:

+ +
let myAge = 17;
+ +

Cadenas de caracteres (Strings)

+ +

Las strings (cadenas) son piezas de texto. Cuando le das a una variable un valor de cadena, debes encerrarlo entre comillas simples o dobles; de lo contrario, JavaScript intenta interpretarlo como otro nombre de variable.

+ +
let dolphinGoodbye = 'Hasta luego y gracias por todos los peces';
+ +

Booleanos

+ +

Los booleanos son valores verdadero/falso — pueden tener dos valores, true o false. Estos, generalmente se utilizan para probar una condición, después de lo cual se ejecuta el código según corresponda. Así, por ejemplo, un caso simple sería:

+ +
let iAmAlive = true;
+ +

Mientras que en realidad se usaría más así:

+ +
let test = 6 < 3;
+ +

Aquí se está usando el operador "menor que" (<) para probar si 6 es menor que 3. Como era de esperar, devuelve false, ¡porque 6 no es menor que 3! Aprenderás mucho más sobre estos operadores más adelante en el curso.

+ +

Arreglos

+ +

Un arreglo es un objeto único que contiene múltiples valores encerrados entre corchetes y separados por comas. Intenta ingresar las siguientes líneas en tu consola:

+ +
let myNameArray = ['Chris', 'Bob', 'Jim'];
+let myNumberArray = [10, 15, 40];
+ +

Una vez que se definen estos arreglos, puedes acceder a cada valor por su ubicación dentro del arreglo. Prueba estas líneas:

+ +
myNameArray[0]; // debería devolver 'Chris'
+myNumberArray[2]; // debe devolver 40
+ +

Los corchetes especifican un valor de índice correspondiente a la posición del valor que deseas devolver. Posiblemente hayas notado que los arreglos en JavaScript tienen índice cero: el primer elemento está en el índice 0.

+ +

Aprenderás mucho más sobre los arreglos en un futuro artículo.

+ +

Objetos

+ +

En programación, un objeto es una estructura de código que modela un objeto de la vida real. Puedes tener un objeto simple que represente una caja y contenga información sobre su ancho, largo y alto, o podrías tener un objeto que represente a una persona y contenga datos sobre su nombre, estatura, peso, qué idioma habla, cómo saludarlo, y más.

+ +

Intenta ingresar la siguiente línea en tu consola:

+ +
let dog = { name : 'Spot', breed : 'Dalmatian' };
+ +

Para recuperar la información almacenada en el objeto, puedes utilizar la siguiente sintaxis:

+ +
dog.name
+ +

Por ahora, no veremos más objetos. Puedes obtener más información sobre ellos en un futuro módulo.

+ +

Tipado dinámico

+ +

JavaScript es un "lenguaje tipado dinámicamente", lo cual significa que, a diferencia de otros lenguajes, no es necesario especificar qué tipo de datos contendrá una variable (números, cadenas, arreglos, etc.).

+ +

Por ejemplo, si declaras una variable y le das un valor entre comillas, el navegador trata a la variable como una cadena (string):

+ +
let myString = 'Hello';
+ +

Incluso si el valor contiene números, sigue siendo una cadena, así que ten cuidado:

+ +
let myNumber = '500'; // Vaya, esto sigue siendo una cadena
+typeof myNumber;
+myNumber = 500; // mucho mejor — ahora este es un número
+typeof myNumber;
+ +

Intenta ingresar las cuatro líneas anteriores en tu consola una por una y ve cuáles son los resultados. Notarás que estamos usando un operador especial llamado {{jsxref("Operadores/typeof", "typeof")}} — esto devuelve el tipo de datos de la variable que escribes después. La primera vez que se llama, debe devolver string, ya que en ese punto la variable myNumber contiene una cadena, '500'. Échale un vistazo y ve qué devuelve la segunda vez que lo llamas.

+ +

Constantes en JavaScript

+ +

Muchos lenguajes de programación tienen el concepto de una constante — un valor que, una vez declarado no se puede cambiar. Hay muchas razones por las que querrías hacer esto, desde la seguridad (si un script de un tercero cambia dichos valores, podría causar problemas) hasta la depuración y la comprensión del código (es más difícil cambiar accidentalmente valores que no se deben cambiar y estropear cosas claras).

+ +

En los primeros días de JavaScript, las constantes no existían. En JavaScript moderno, tenemos la palabra clave const, que nos permite almacenar valores que nunca se pueden cambiar:

+ +
const daysInWeek = 7;
+const hoursInDay = 24;
+ +

const funciona exactamente de la misma manera que let, excepto que a const no le puedes dar un nuevo valor. En el siguiente ejemplo, la segunda línea arrojará un error:

+ +
const daysInWeek = 7;
+daysInWeek = 8;
+ +

¡Pon a prueba tus habilidades!

+ +

Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Puedes encontrar más pruebas para verificar que has retenido esta información antes de continuar — consulta Pon a prueba tus habilidades: variables.

+ +

Resumen

+ +

A estas alturas, deberías saber bastante sobre las variables de JavaScript y cómo crearlas. En el próximo artículo, nos centraremos en los números con más detalle, y veremos cómo hacer matemáticas básicas en JavaScript.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Maths", "Learn/JavaScript/First_steps")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/first_steps/what_went_wrong/index.html b/files/es/learn/javascript/first_steps/what_went_wrong/index.html new file mode 100644 index 0000000000..af36c20852 --- /dev/null +++ b/files/es/learn/javascript/first_steps/what_went_wrong/index.html @@ -0,0 +1,268 @@ +--- +title: ¿Qué ha salido mal? Corrigiendo JavaScript +slug: Learn/JavaScript/First_steps/What_went_wrong +tags: + - Aprender + - Artículo + - CodingScripting + - Debugging + - Depurando + - Error + - Herramientas de Desarrollador + - JavaScript + - Novato + - Principiante + - Tutorial + - console.log + - depurar + - 'l10n:priority' +translation_of: Learn/JavaScript/First_steps/What_went_wrong +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}
+ +

Cuando construiste el juego "Adivina el número" en el artículo anterior, es posible que hayas descubierto que no funcionó. Tranquilo — este artículo tiene como objetivo evitar que te rasques la cabeza por este tipo de problemas brindándote algunos consejos sobre cómo encontrar y corregir errores en programas JavaScript.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, comprensión básica de HTML y CSS, comprensión de lo que es JavaScript.
Objetivo:Para ganar habilidad y confianza para comenzar a solucionar problemas en tu propio código.
+ +

Tipos de errores

+ +

En general, cuando haces algo mal en el código, hay dos tipos principales de errores con los que te encontrarás:

+ + + +

Bueno, tampoco es así de simple — a medida que profundices hay algunas otras diferencias. Pero las clasificaciones anteriores funcionarán en esta temprana etapa de tu carrera. Veremos ambos tipos en el futuro.

+ +

Un ejemplo erróneo

+ +

Para empezar, regresemos a nuestro juego de adivinan el número — excepto que esta vez vamos a explorar una versión que tiene algunos errores insertados deliberadamente. Ve a GitHub y haz una copia local de number-game-errors.html (puedes verlo en vivo aquí).

+ +
    +
  1. Para comenzar, abre la copia local dentro de tu editor de texto favorito y tu navegador.
  2. +
  3. Intenta jugarlo — notarás que cuando presionas el botón "Enviar respuesta", ¡no funciona!
  4. +
+ +
+

Nota: ¡Posiblemente tengas tu propia versión del ejemplo del juego que no funciona, y quizás la quieras arreglar! Aún así nos gustaría que en el artículo trabajes con nuestra versión, para que puedas aprender las técnicas que estamos enseñando. Después puedes tratar de arreglar tu ejemplo.

+
+ +

En este punto, consultemos la consola del desarrollador para ver si podemos ver algún informe de error de sintaxis y luego tratar de solucionarlo. Abajo aprenderás cómo.

+ +

Solucionar errores de sintaxis

+ +

Anteriormente en este curso, hicimos que escribieras algunos comandos JavaScript simples en la consola JavaScript de las herramientas para desarrolladores (si no recuerdas cómo abrirla en tu navegador, sigue el enlace anterior para descubrirlo). Lo más útil es que la consola te brinda mensajes de error cada vez que ocurre algún error de sintaxis dentro del JavaScript que alimenta al motor JavaScript del navegador. Ahora vayamos a cazar.

+ +
    +
  1. Ve a la pestaña dónde tienes abierto number-game-errors.html y abre tu consola JavaScript. Deberías ver un mensaje de error con las siguientes líneas:
  2. +
  3. Este es un error bastante fácil de rastrear, y el navegador le brinda varios bits de información útil para ayudarte (la captura de pantalla anterior es de Firefox, pero otros navegadores proporcionan información similar). De izquierda a derecha, tenemos: +
      +
    • Una "x" roja para indicar que se trata de un error.
    • +
    • Un mensaje de error para indicar qué salió mal: "TypeError: guessSubmit.addeventListener no es una función"
    • +
    • Un enlace a "Más información" que te lleva a una página de MDN dónde explica detalladamente qué significa este error.
    • +
    • El nombre del archivo JavaScript, que enlaza con la pestaña "Depurador" de las herramientas para desarrolladores. Si sigues este enlace, verás la línea exacta donde se resalta el error.
    • +
    • El número de línea donde está el error y el número de carácter en esa línea donde se detectó el error por primera vez. En este caso, tenemos la línea 86, carácter número 3.
    • +
    +
  4. +
  5. Si miramos la línea 86 en nuestro editor de código, encontraremos esta línea: +
    guessSubmit.addeventListener('click', checkGuess);
    +
  6. +
  7. El mensaje de error dice "guessSubmit.addeventListener no es una función", lo cual significa que el intérprete de JavaScript no reconoce la función que estamos llamando. A menudo, este mensaje de error en realidad significa que hemos escrito algo mal. Si no estás seguro de la ortografía correcta de una parte de la sintaxis, a menudo es bueno buscar la función en MDN. La mejor manera de hacer esto es, en tu navegador favorito, buscar "mdn nombre-de-característica". Aquí hay un atajo para ahorrarte algo de tiempo en esta instancia: addEventListener().
  8. +
  9. Entonces, al mirar esta página, ¡el error parece ser que hemos escrito mal el nombre de la función!. Recuerda que JavaScript distingue entre mayúsculas y minúsculas, por lo que cualquier pequeña diferencia en la ortografía o en mayúsculas provocará un error. Cambiar addeventListener a addEventListener debería solucionar este problema. Hazlo ahora.
  10. +
+ +
+

Nota: Échale un vistazo a nuestra página de referencia TypeError: "x" no es una función para obtener más detalles sobre este error.

+
+ +

Errores sintácticos, segunda ronda

+ +
    +
  1. Guarda tu página y refréscala, ahora deberías ver que el error ha desaparecido.
  2. +
  3. Ahora, si intentas ingresar un número y presionas el botón "Enviar respuesta", verás... ¡otro error!
  4. +
  5. Esta vez, el error que se informa es "TypeError: lowOrHi es nulo", en la línea 78. +
    Nota: Null es un valor especial que significa "nada" o "sin valor". Por lo tanto, lowOrHi ha sido declarado e iniciado, pero no con algún valor significativo — no tiene tipo ni valor.
    + +
    Nota: Este error no apareció tan pronto como se cargó la página porque este error ocurrió dentro de una función (dentro del bloque checkGuess() {...}). Como pronto aprenderás con más detalle en nuestro artículo de funciones, el código dentro de las funciones se ejecuta en un ámbito separado que el código fuera de las funciones. En este caso, el código no se ejecutó y el error no se lanzó hasta que la función checkGuess() se ejecutó en la línea 86.
    +
  6. +
  7. Échale un vistazo a la línea 78 y verás el siguiente código: +
    lowOrHi.textContent = '¡El número es muy grande!';
    +
  8. +
  9. Esta línea está intentando establecer la propiedad textContent de la constante lowOrHi en una cadena de texto, pero no funciona porque lowOrHi no contiene lo que es supone. Veamos por qué es así — intenta buscar otras instancias de lowOrHi en el código. La primera instancia que encontrarás en JavaScript está en la línea 48: +
    const lowOrHi = document.querySelector('lowOrHi');
    +
  10. +
  11. En este punto, estamos intentando hacer que la variable contenga una referencia a un elemento en el HTML del documento. Comprobemos si el valor es null después de ejecutar esta línea. Agrega el siguiente código en la línea 49: +
    console.log(lowOrHi);
    + +
    +

    Nota: console.log() es una función de depuración realmente útil que imprime un valor en la consola. Por lo tanto, imprimirá el valor de lowOrHi en la consola tan pronto como intentemos configurarlo en la línea 48.

    +
    +
  12. +
  13. Guarda y refresca, y ahora deberías ver el resultado de console.log() en tu consola. Efectivamente, el valor de lowOrHies null en este punto, así que definitivamente hay un problema con la línea 48.
  14. +
  15. Pensemos en cuál podría ser el problema. La línea 48 está utilizando un método document.querySelector() para obtener una referencia a un elemento seleccionándolo con un selector CSS. Buscando más adelante en nuestro archivo, podemos encontrar el párrafo en cuestión: +
    <p class="lowOrHi"></p>
    +
  16. +
  17. Entonces necesitamos un selector de clase aquí, que comienza con un punto (.), pero el selector que se pasa al método querySelector() en la línea 48 no tiene punto. ¡Este podría ser el problema! Intenta cambiar lowOrHi a .lowOrHi en la línea 48.
  18. +
  19. Ahora guarda y refresca nuevamente, y tu declaración console.log() debería devolver el elemento <p> que queremos. ¡Uf! ¡Otro error solucionado! Ahora puedes eliminar tu línea console.log(), o mantenerla como referencia más adelante — tu elección.
  20. +
+ +
+

Nota: Consulta nuestra página de referencia TypeError: "x" (no) es "y" para obtener más detalles sobre este error.

+
+ +

Errores sintácticos, tercera ronda

+ +
    +
  1. Ahora, si intentas jugar de nuevo, deberías tener más éxito — el juego debería funcionar absolutamente bien, hasta que termines el juego, ya sea adivinando el número correcto o porque agotaste los intentos.
  2. +
  3. En ese momento, el juego vuelve a fallar y lanza el mismo error que obtuvimos al principio: "TypeError: resetButton.addeventListener no es una función". Sin embargo, esta vez aparece como procedente de la línea 94.
  4. +
  5. Mirando la línea número 94, es fácil ver que hemos cometido el mismo error aquí. Nuevamente, solo necesitamos cambiar addeventListener a .addEventListener. Hazlo ahora.
  6. +
+ +

Un error de lógica

+ +

En este punto, el juego debería trabajar bien, sin embargo, después de jugar varias veces, sin duda notarás que el número "aleatorio" que debes adivinar siempre es 1. ¡Definitivamente no es exactamente como queremos que se desarrolle el juego!

+ +

Obviamente hay un problema en la lógica del juego en alguna parte — el juego no devuelve un error; simplemente no está jugando bien.

+ +
    +
  1. Busca la variable randomNumber y las líneas donde se establece primero el número aleatorio. La instancia que almacena el número aleatorio que queremos adivinar al comienzo del juego debe estar alrededor de la línea número 44: + +
    let randomNumber = Math.floor(Math.random()) + 1;
    + Y la que genera el número aleatorio antes de cada juego subsiguiente está alrededor de la línea 113:
  2. +
  3. +
    randomNumber = Math.floor(Math.random()) + 1;
    +
  4. +
  5. Para comprobar si estas líneas son realmente el problema, volvamos a echar mano de nuestra amiga console.log() — inserta la siguiente línea directamente debajo de cada una de las dos líneas anteriores: +
    console.log(randomNumber);
    +
  6. +
  7. Guarda y refresca, luego juega un par de veces — verás que randomNumber es igual a 1 en cada punto en el que se registra en la consola.
  8. +
+ +

Desentrañando la lógica

+ +

Para solucionar esto, consideremos cómo está funcionando esta línea. Primero, invocamos a Math.random(), que genera un número decimal aleatorio entre 0 y 1, p. ej. 0.5675493843.

+ +
Math.random()
+ +

A continuación, pasamos el resultado de invocar a Math.random() a Math.floor(), que redondea el número pasado al número entero más cercano. Luego agregamos 1 a ese resultado:

+ +
Math.floor(Math.random()) + 1
+ +

Redondear un número decimal aleatorio entre 0 y 1 siempre devolverá 0, por lo que agregarle 1 siempre devolverá 1. Necesitamos multiplicar el número aleatorio por 100 antes de redondearlo hacia abajo. Lo siguiente nos daría un número aleatorio entre 0 y 99:

+ +
Math.floor(Math.random()*100);
+ +

De ahí que queramos sumar 1, para darnos un número aleatorio entre 1 y 100:

+ +
Math.floor(Math.random()*100) + 1;
+ +

Intenta actualizar ambas líneas de esta manera, luego guarda y refresca — ¡el juego ahora debería trabajar como pretendemos!

+ +

Otros errores comunes

+ +

Hay otros errores comunes que encontrarás en tu código. Esta sección destaca la mayoría de ellos.

+ +

SyntaxError: falta ; antes de la declaración

+ +

Este error generalmente significa que has omitido un punto y coma al final de una de sus líneas de código, pero a veces puede ser más críptico. Por ejemplo, si cambiamos esta línea dentro de la función checkGuess():

+ +
var userGuess = Number(guessField.value);
+ +

a

+ +
var userGuess === Number(guessField.value);
+ +

Lanza este error porque cree que estás intentando hacer algo diferente. Debes asegurarte de no confundir el operador de asignación (=), que establece una variable para que sea igual a un valor — con el operador de igualdad estricta (===), que prueba si un valor es igual a otro y devuelve un resultado true/false.

+ +
+

Nota: Ve más detalles sobre este error en nuestra página de referencia SyntaxError: falta ; antes de la declaración.

+
+ +

El programa siempre dice que has ganado, independientemente de lo que hayas ingresado

+ +

Este podría ser otro síntoma de confusión entre la asignación y los operadores de igualdad estricta. Por ejemplo, si cambiamos esta línea dentro de checkGuess():

+ +
if (userGuess === randomNumber) {
+ +

a

+ +
if (userGuess = randomNumber) {
+ +

la prueba siempre devolvería true, haciendo que el programa informe que se ganó el juego. ¡Ten cuidado!

+ +

SyntaxError: falta ) después de la lista de argumentos

+ +

Este es bastante simple — generalmente significa que olvidaste colocar el paréntesis de cierre al final de una llamada a una función/método.

+ +
+

Nota: Ve más detalles sobre este error en nuestra página de referencia SyntaxError: falta ) después de la lista de argumentos.

+
+ +

SyntaxError: falta : después de la propiedad id

+ +

Este error generalmente se relaciona con un objeto JavaScript formado incorrectamente, pero en este caso logramos obtenerlo cambiando

+ +
function checkGuess() {
+ +

a

+ +
function checkGuess( {
+ +

Esto ha hecho que el navegador piense que estamos tratando de pasar el contenido de la función a la función como un argumento. ¡Cuidado con esos paréntesis!

+ +

SyntaxError: falta } después del cuerpo de la función

+ +

Esto es fácil — generalmente significa que has omitido una de tus llaves de una función o estructura condicional. Obtuvimos este error al eliminar una de las llaves de cierre cerca de la parte inferior de la función checkGuess().

+ +

SyntaxError: esperaba expresión, obtuve 'string' o SyntaxError: Cadena literal sin terminar

+ +

Estos errores generalmente significan que has omitido las comillas de apertura o cierre de un valor de cadena. En el primer error anterior, string se reemplazaría con los caracteres inesperados que encontró el navegador en lugar de una comilla al comienzo de una cadena. El segundo error significa que la cadena no se ha terminado con comillas.

+ +

Para todos estos errores, piensa en cómo abordamos los ejemplos que vimos en el tutorial. Cuando surge un error, mira el número de línea que te dan, ve a esa línea y revísala para detectar lo que está mal. Ten en cuenta que el error no necesariamente estará en esa línea, y también que el error podría no ser causado por el mismo problema que mencionamos anteriormente.

+ +
+

Nota: Obtén más detalles sobre estos errores en nuestras páginas de referencia SyntaxError: símbolo inesperado y SyntaxError: cadena literal sin terminar.

+
+ +

Resumen

+ +

Ahí lo tienes, los conceptos básicos para descubrir errores en programas sencillos de JavaScript. No siempre será tan sencillo averiguar qué está mal en tu código, pero al menos esto te ahorrará algunas horas de sueño y te permitirá progresar un poco más rápido cuando las cosas no salgan bien, especialmente en las primeras etapas de tu viaje de aprendizaje.

+ +

Ve también

+ +
+ +
+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}

+ +

En este modulo

+ + diff --git a/files/es/learn/javascript/howto/index.html b/files/es/learn/javascript/howto/index.html new file mode 100644 index 0000000000..b0abd6c044 --- /dev/null +++ b/files/es/learn/javascript/howto/index.html @@ -0,0 +1,317 @@ +--- +title: Resuelva problemas comunes en su código JavaScript +slug: Learn/JavaScript/Howto +tags: + - Aprendizaje + - JavaScript + - Principante +translation_of: Learn/JavaScript/Howto +--- +
{{LearnSidebar}}
+ +

+ +

Los siguientes enlaces apuntan a soluciones a problemas comunes de todos los días que deberá solucionar para que su código JavaScript se ejecute correctamente..

+ +

Errores comunes de principiante

+ +

Correcta ortografía y casing

+ + + +

Si su código no funciona y / o el navegador se queja de que algo no está definido, verifique que haya escrito todos sus nombres de variables, nombres de funciones, etc. correctamente.  

+ + + +

Algunas funciones comunes del navegador incorporado que causan problemas son:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CorrectoIncorrecto
getElementsByTagName()getElementbyTagName()
getElementsByName()getElementByName()
getElementsByClassName()getElementByClassName()
getElementById()getElementsById()
+ +

Posición de punto y coma

+ +

Debes estar seguro de no colocar ningún punto y coma incorrectamente. Por ejemplo:

+ + + + + + + + + + + + +
CorrectoIncorrecto
elem.style.color = 'red';elem.style.color = 'red;'
+ +

Funciones

+ +

Hay una serie de cosas que pueden salir mal con la funciones.

+ +

Uno de los errores más comunes es declarar una función, pero no llamarla a ninguna parte, Por ejemplo:

+ +
function miFuncion() {
+  alert('Esta es mi funcion.');
+};
+ +

Este código no hará nada a menos que lo llame, por ejemplo con

+ +
miFuncion();
+ +

Alcance de la función

+ + + +

Recuerda que las funciones tienen su propio alcance — no puedes acceder a un valor de variable establecido dentro de una función desde fuera de la función, a menos que haya declarado la variable globalmente (es decir, no dentro de ninguna función), o retornar el valor fuera de la función.

+ +

Ejecución de código después de una declaración de retorno (Return)

+ + + +

Recuerde también que cuando devuelve un valor de una función, el intérprete de JavaScript sale de la función — ningún código declarado después de que se ejecute la declaración de devolución (Return).

+ +

De hecho, algunos navegadores (como Firefox) le darán un mensaje de error en la consola del desarrollador si tiene código después de una declaración de devolución. Firefox te ofrece "código inalcanzable después de la declaración de devolución".

+ +

Mas abajo podemos observar una función de saludo, posterior a retornar intentamos asignar a la variable x, el valor de la propiedad que viene en la función. Esto nunca ocurrira ya que posterior a retornar un valor se sale del contexto función. En pocas palabras jamas ocurrira la asignación.

+ +

Ejemplo de una declaración posterior a una declaración de retorno:

+ +
function saludo(nombre){
+ return "Hola, " + nombre + " que bueno que volviste";
+ var x = nombre; //Esta linea jamas se ejecutara ya que viene despues de un retorno
+}
+ +

Notación de objetos versus asignación normal

+ + + +

Cuando asigna algo normalmente en JavaScript, utiliza un solo signo igual, por ejemplo:

+ +
const miNumero= 0;
+ +

Esto no funciona en los Objetos, sin embargo, con los objetos, debe separar los nombres de los miembros de sus valores mediante dos puntos y separar cada miembro con una coma, por ejemplo:

+ +
const miObjeto= {
+  nombre: 'Felipe',
+  edad: 27
+}
+ +

Definiciones básicas

+ +
+ + + +
+ +

Casos de uso básico

+ +
+ + +
+

Matrices (Arrays)

+ + + +

Depuración de JavaScript

+ + + + + +

Para obtener más información sobre la depuración de JavaScript, consulte Manejo de problemas comunes de JavaScript ; Consulte también Otros errores comunes para obtener una descripción de los errores comunes.

+ +

Tomar decisiones en el código

+ + + +

Bucle / Iteración

+ + +
+
+ +

Casos de uso intermedio

+ +
+ + + +
diff --git a/files/es/learn/javascript/index.html b/files/es/learn/javascript/index.html new file mode 100644 index 0000000000..4703c68749 --- /dev/null +++ b/files/es/learn/javascript/index.html @@ -0,0 +1,80 @@ +--- +title: JavaScript +slug: Learn/JavaScript +tags: + - JavaScript + - Novato + - Principiante + - Tema + - aterrizando + - 'l10n:priority' + - modulo + - princiante JavaScript +translation_of: Learn/JavaScript +--- +
{{LearnSidebar}}
+ +

{{Glossary("JavaScript")}} es un lenguaje de programación que te permite implementar cosas complejas en páginas web. Cada vez que una página web hace algo más que sentarse ahí y mostrar información estática para que la veas — mostrando actualizaciones de contenido oportunas, mapas interactivos, gráficos animados 2D/3D, desplazando máquinas reproductoras de video, o más, puedes apostar que probablemente JavaScript esté involucrado .

+ +
+

¿Quieres convertirte en un desarrollador web front-end?

+ +

Hemos elaborado un curso que incluye toda la información esencial que necesitas para trabajar hacia tu objetivo.

+ +

Empezar

+
+ +

Prerrequisitos

+ +

Se puede decir que JavaScript es más difícil de aprender que tecnologías relacionadas como HTML y CSS. Antes de intentar aprender JavaScript, se recomienda encarecidamente que te familiarices con al menos estas dos tecnologías primero, y quizás también con otras. Comienza trabajando con los siguientes módulos:

+ + + +

Tener experiencia previa con otros lenguajes de programación también puede ayudar.

+ +

Después de familiarizarte con los conceptos básicos de JavaScript, deberías estar en condiciones de aprender sobre temas más avanzados, por ejemplo:

+ + + +

Módulos

+ +

Este tema contiene los siguientes módulos, en un orden sugerido para trabajar con ellos.

+ +
+
Primeros pasos en JavaScript
+
En nuestro primer módulo de JavaScript, primero respondemos algunas preguntas fundamentales como "¿qué es JavaScript?", "¿Cómo se ve?" y "¿qué puede hacer?", antes de pasar a guiarte por tu primera experiencia práctica de escribir JavaScript. Después de eso, discutimos en detalle algunas características clave de JavaScript, tal como variables, cadenas, números y arreglos.
+
Bloques de construcción de JavaScript
+
En este módulo, continuamos con nuestra cobertura de todas las características fundamentales clave de JavaScript, centrando nuestra atención en los tipos de bloques de código que se encuentran comúnmente, como declaraciones condicionales, bucles, funciones y eventos. Ya has visto estas cosas en el curso, pero solo de pasada; aquí lo discutiremos todas explícitamente.
+
Introducción a los objetos JavaScript
+
En JavaScript, la mayoría de las cosas son objetos, desde las características principales de JavaScript como cadenas y arreglos hasta las APIs del navegador creadas sobre JavaScript. Incluso puedes crear tus propios objetos para encapsular funciones y variables relacionadas en paquetes eficientes. Es importante comprender la naturaleza orientada a objetos de JavaScript si deseas ir más allá con tu conocimiento del lenguaje y escribir código más eficiente, por lo tanto, te proporcionamos este módulo para ayudarte. Aquí enseñamos la teoría y la sintaxis de objetos en detalle, vemos cómo crear tus propios objetos y explicamos qué son los datos JSON y cómo trabajar con ellos.
+
JavaScript asíncrono
+
+

En este módulo, echamos un vistazo a JavaScript asíncrono, por qué es importante y cómo se puede utilizar para manejar de forma eficaz posibles operaciones de bloqueo, como la obtención de recursos desde un servidor.

+
+
APIs web de lado del cliente
+
Al escribir JavaScript de lado del cliente para sitios web o aplicaciones, no irás muy lejos antes de comenzar a usar las APIs — interfaces para manipular diferentes aspectos del navegador y el sistema operativo en el que se ejecuta el sitio, o incluso datos de otros sitios web o servicios. En este módulo, exploraremos qué son las APIs y cómo utilizar algunas de las APIs más populares que encontrarás a menudo en tu trabajo de desarrollo. 
+
+ +

Resolver problemas comunes de JavaScript

+ +

Usar JavaScript para resolver problemas comunes proporciona enlaces a secciones de contenido que explican cómo usar JavaScript para resolver problemas muy comunes al crear una página web.

+ +

Ve también

+ +
+
JavaScript en MDN
+
El principal punto de entrada para la documentación básica de JavaScript en MDN — aquí es donde encontrarás documentos de referencia extensos sobre todos los aspectos del lenguaje JavaScript y algunos tutoriales avanzados dirigidos a JavaScripters experimentados.
+
Aprende JavaScript
+
Un excelente recurso para los aspirantes a desarrolladores web — aprende JavaScript en un entorno interactivo, con lecciones breves y pruebas interactivas, guiado por una evaluación automatizada. Las primeras 40 lecciones son gratuitas y el curso completo está disponible por un pequeño pago único.
+
Fundamentos de JavaScript en EXLskills
+
Aprende JavaScript de forma gratuita con el curso de código abierto EXLskills que presenta todo lo que necesitas para comenzar a crear aplicaciones en JavaScript.
+
Codificación de Matemáticas
+
Una excelente serie de tutoriales en video para enseñar las matemáticas que necesitas comprender para ser un programador eficaz, por Keith Peters.
+
diff --git a/files/es/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/es/learn/javascript/objects/adding_bouncing_balls_features/index.html new file mode 100644 index 0000000000..c2aa7a9985 --- /dev/null +++ b/files/es/learn/javascript/objects/adding_bouncing_balls_features/index.html @@ -0,0 +1,205 @@ +--- +title: Añadiendo características a nuestra demo de bouncing balls +slug: Learn/JavaScript/Objects/Adding_bouncing_balls_features +tags: + - Aprender + - Evaluación + - JavaScript + - Objetos + - Orientado a objetos + - Principiante +translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}
+ +

En esta evaluación, se espera que use la demo de bouncing balls del artículo anterior como punto de partida y le agregue algunas características nuevas e interesantes.

+ + + + + + + + + + + + +
Prerrequisitos:Antes de intentar esta evaluación, debería haber revisado todos los artículos de este módulo.
Objetivo:Para probar la comprensión de objetos JavaScript y construcciones orientadas a objetos.
+ +

Punto de partida

+ +

Para iniciar esta evaluación, haz una copia local de  index-finished.html, style.css, y main-finished.js de nuestro último artículo en un nuevo directorio en tu ordenador.

+ +
+

Nota: Alternativamente, puede usar un sitio como JSBinThimble para hacer su evaluación. Puede pegar el HTML, CSS y JavaScript en uno de estos editores en línea. Si el editor en línea que está utilizando no tiene paneles JavaScript / CSS separados, sientase libre de poner en linea elementos <script>/<style> dentro de la página.

+
+ +

Resumen del proyecto

+ +

Nuestra demostración de la pelota hinchable es divertida, pero ahora queremos que sea un poco más interactiva agregando un círculo maligno controlado por el usuario, que se los comería si los atrapa. Tambien queremos testar nuestras destrezas como constructores de objetos creando un objeto Shape() genérico de que puedan heredar nuestra pelota y el círculo maligno. Finalmente, queremos añadir una puntuación para seguir el número de bolas que quedan por capturar.

+ +

La siguiente captura de pantalla te da una idea de cómo debería verse el programa final.

+ +

+ + + +

Para darle una idea eche un vistazo al ejemplo final (¡no mire el código fuente!)

+ +

Pasos para completar

+ +

Las siguientes secciones describen lo que debe hacer.

+ +

Creando nuestro nuevos objetos

+ +

Primero de todo, cambia la constructora existente de Ball() para que se convierta en un constructor Shape() y añade un nuevo constructor Ball():

+ +
    +
  1. El constructor Shape() debe definir las propiedades x, y, velX, y velY del mismo modo que lo hacía el constructor Ball() constructor original, pero no las propiedades color y size.
  2. +
  3. También debe definir una nueva propiedad exists, que se utiliza para realizar un seguimiento de si existen las bolas en el programa (no se han comido por el círculo maligno). Debe ser un boolean (true/false).
  4. +
  5. El constructor Ball() debe heredar las propiedades x, y, velX, velY, y exists del constructor Shape().
  6. +
  7. También debe definir propiedades color y size, como el constructor original Ball() hacía.
  8. +
  9. Recuerda configurar el prototype del constructor Ball() correctamente.
  10. +
+ +

Los métodos de la pelota draw(), update(), y collisionDetect() deben ser capaces de permanecer exactamente igual que antes.

+ +

También necesitas añadir un parámetro nuevo a la llamada del constructor new Ball() ( ... )  — El parámetro exists debe ser el quinto parámetro y debe tener un valor true.

+ +

En este punto, intente volver a cargar el código; debería funcionar igual que antes, con nuestros objetos rediseñados.

+ +

Definiendo EvilCircle()

+ +

Ahora es el momento de conocer al chico malo: ¡el EvilCircle()! Nuestro juego solo involucrará un círculo malvado, pero lo vamos a seguir definiendo usando un constructor que hereda de Shape() para que tengas algo de práctica. Es posible que desee agregar otro círculo a la aplicación más adelante que pueda ser controlado por otro jugador o tener varios círculos malvados controlados por computadora. Probablemente no vas a dominar el mundo con un solo círculo maligno, pero servirá para esta evaluación.

+ +

El constructor  EvilCircle() debe heredar x, y, velX, velY, y exists from Shape(), pero velX y velY debe ser igual a 20.

+ +

Debería hacer algo como Shape.call(this, x, y, 20, 20, exists);

+ +

Debe definir también sus propias propiedades, como las siguientes:

+ + + +

Otra vez, recuerda definir tus propiedades heredadas como parámetros en el constructor, y configura las propiedades prototype y constructor properties correc.tamente

+ +

Definiendo los métodos de EvilCircle()

+ +

EvilCircle() debe tener cuatro métodos como se desciben a continuación.

+ +

draw()

+ +

Este método tiene el mismo propósito que el método draw()de Ball(): Se encarga de dibujar la instancia del objeto en el lienzo. Funcionarán de una forma muy similar, así que puedes empezar copiando la definición de Ball.prototype.draw. Luego deberías hacer los siguientes cambios.:

+ + + +

checkBounds()

+ +

Este método hara lo mismo que la primera parte de la función update() de Ball() — mire para ver si el círculo maligno va a salir del borde de la pantalla y evite que lo haga. De nuevo, puede copiar la mayoría de la definición de Ball.prototype.update, hay algunos cambios que debe hacer:

+ + + +

setControls()

+ +

Este método agregará un detector de eventos onkeydown al objeto window para que cuando se presionen ciertas teclas del teclado, podamos mover el círculo maligno. El siguiente bloque de código debe colocarse dentro de la definición del método:

+ +
var _this = this;
+window.onkeydown = function(e) {
+    if (e.keyCode === 65) {
+      _this.x -= _this.velX;
+    } else if (e.keyCode === 68) {
+      _this.x += _this.velX;
+    } else if (e.keyCode === 87) {
+      _this.y -= _this.velY;
+    } else if (e.keyCode === 83) {
+      _this.y += _this.velY;
+    }
+  }
+ +

Por tanto cuando se presiona una tecla, el evento del objeto keyCode se consulta para averiguar que tecla se ha presionado. Si es uno de los cuatro representados por los códigos clave especificados, entonces el círculo maligno se moverá a la izquierda / derecha / arriba / abajo.

+ + + +

collisionDetect()

+ +

Este método actuará de una forma muy similar al método collisionDetect() de Ball(), así que puede usar una copia de eso como una base para el nuevo método. Pero hay algunas diferencias:

+ + + +

Trayendo el círculo del mal al programa.

+ +

Ahora que hemos definido el círculo maligno, debemos hacerlo aparecer en nuestra escena. Para hacerlo, necesitas hacer alguno cambios a la función loop().

+ + + +

Implementando el contador de puntuación.

+ +

Para implementar el contador de puntuación sigue estos pasos:

+ +
    +
  1. En tu archivo HTML añade un elemento {{HTMLElement("p")}} justo debajo del elemento {{HTMLElement("h1")}} que contiene el texto "Ball count: ".
  2. +
  3. En tu archivo CSS, agregue la siguiente regla en la parte inferior: +
    p {
    +  position: absolute;
    +  margin: 0;
    +  top: 35px;
    +  right: 5px;
    +  color: #aaa;
    +}
    +
  4. +
  5. En su JavaScript, realice las siguientes actualizaciones: +
      +
    • Cree una variable que almacene una referencia al párrafo.
    • +
    • Mantenga un recuento de la cantidad de bolas en la pantalla de alguna manera.
    • +
    • Incrementa el conteo y muestra el número actualizado de bolas cada vez que se agrega una bola a la escena.
    • +
    • Disminuye el conteo y muestra el número actualizado de bolas cada vez que el círculo maligno se come una bola (hace que no exista).
    • +
    +
  6. +
+ +

Consejos

+ + + +

Evaluación

+ +

Si está siguiendo esta evaluación como parte de un curso organizado, debe poder entregar su trabajo a su maestro / mentor para que lo marque. Si está aprendiendo solo, puede obtener la guía de calificación con bastante facilidad preguntando en el discussion thread for this exercise, o en el #mdn IRC channel en Mozilla IRC. Prueba a hacer el ejercicio primero — no hay nada que ganar con trampa!

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/objects/basics/index.html b/files/es/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..a04cdb6a81 --- /dev/null +++ b/files/es/learn/javascript/objects/basics/index.html @@ -0,0 +1,259 @@ +--- +title: Conceptos básicos de los objetos JavaScript +slug: Learn/JavaScript/Objects/Basics +tags: + - API + - Aprender + - Artículo + - JavaScript + - Novato + - Object + - Objeto + - Principiante + - Sintaxis + - instancia + - 'l10n:priority' + - notación de corchetes + - notación de punto + - objeto literal + - tehoría + - this +translation_of: Learn/JavaScript/Objects/Basics +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}
+ +

En éste artículo, veremos fundamentos de sintaxis de los objetos de JavaScript y revisaremos algunas características de JavaScript que ya hemos analizado anteriormente en el curso, reiterando el hecho de que muchas de las funciones con las que ya has tratado de hecho son objetos.

+ + + + + + + + + + + + +
Prerrequisitos:Conocimientos básicos de informática, conocimientos básicos de HTML y CSS, familiaridad con los principios básicos de JavaScript (consulta Primeros pasos y Bloques de construcción).
Objetivo:Para comprender la teoría básica detrás de la programación orientada a objetos, cómo esto se relaciona con JavaScript ("la mayoría de las cosas son objetos") y cómo empezar a trabajar con objetos de JavaScript.
+ +

Conceptos básicos de objeto

+ +

Un objeto es una colección de datos relacionados y/o funcionalidad (que generalmente consta de algunas variables y funciones, que se denominan propiedades y métodos cuando están dentro de objetos). Vamos a trabajar a través de un ejemplo para mostrate cómo son.

+ +

Para empezar, haz una copia local de nuestro archivo oojs.html . Esto contiene muy poco: un elemento {{HTMLElement ("script")}} para que escribas tu código fuente en él. Lo usaremos como base para explorar la sintaxis básica de los objetos.

+ +

Al igual que con muchas cosas en JavaScript, la creación de un objeto a menudo comienza con la definición e iniciación de una variable. Intenta ingresar lo siguiente debajo del código JavaScript que ya está en tu archivo, luego guarda y actualiza:

+ +
var persona = {};
+ +

Si ingresas persona en tu entrada de texto y presionas el botón, debes obtener el siguiente resultado:

+ +
[objeto Objeto]
+ +

¡Felicidades!, acabas de crear tu primer objeto. ¡Trabajo realizado! Pero este es un objeto vacío, por lo que realmente no podemos hacer mucho con él. Actualicemos nuestro objeto para que se vea así:

+ +
var persona = {
+  nombre: ['Bob', 'Smith'],
+  edad: 32,
+  genero: 'masculino',
+  intereses: ['música', 'esquí'],
+  bio: function () {
+    alert(this.nombre[0] + '' + this.nombre[1] + ' tiene ' + this.edad + ' años. Le gusta ' + this.intereses[0] + ' y ' + this.intereses[1] + '.');
+  },
+  saludo: function() {
+    alert('Hola, Soy '+ this.nombre[0] + '. ');
+  }
+};
+
+ +

Después de guardar y actualizar, intenta ingresar algunos de los siguientes en tu entrada de texto:

+ +
persona.nombre
+persona.nombre[0]
+persona.edad
+persona.intereses[1]
+persona.bio()
+persona.saludo()
+ +

¡Ahora tienes algunos datos y funcionalidades dentro de tu objeto, y ahora puedes acceder a ellos con una sintaxis simple y agradable!

+ +
+

Nota: Si tienes problemas para hacer que esto funcione, intenta comparar tu código con nuestra versión - ve oojs-finished.html (también ve que se ejecuta en vivo). La versión en vivo te dará una pantalla en blanco, pero eso está bien. De nuevo, abre tu devtools e intenta escribir los comandos anteriores para ver la estructura del objeto.

+
+ +

Entonces, ¿qué está pasando aquí? Bien, un objeto se compone de varios miembros, cada uno de los cuales tiene un nombre (por ejemplo, nombre y edad) y un valor (por ejemplo, ['Bob', 'Smith'] y 32). Cada par nombre/valor debe estar separado por una coma, y el nombre y el valor en cada caso están separados por dos puntos. La sintaxis siempre sigue este patrón:

+ +
var nombreObjeto = {
+  miembro1Nombre: miembro1Valor,
+  miembro2Nombre: miembro2Valor,
+  miembro3Nombre: miembro3Valor
+}
+ +

El valor de un miembro de un objeto puede ser prácticamente cualquier cosa: en nuestro objeto persona tenemos una cadena de texto, un número, dos arreglos y dos funciones. Los primeros cuatro elementos son elementos de datos y se denominan propiedades del objeto. Los dos últimos elementos son funciones que le permiten al objeto hacer algo con esos datos, y se les denomina métodos del objeto.

+ +

Un objeto como este se conoce como un objeto literal — literalmente hemos escrito el contenido del objeto tal como lo fuimos creando. Esto está en contraste con los objetos instanciados de las clases, que veremos más adelante.

+ +

Es muy común crear un objeto utilizando un objeto literal cuando deseas transferir una serie de elementos de datos relacionados y estructurados de alguna manera, por ejemplo, enviando una solicitud al servidor para ponerla en una base de datos. Enviar un solo objeto es mucho más eficiente que enviar varios elementos individualmente, y es más fácil de procesar que con un arreglo, cuando deseas identificar elementos individuales por nombre.

+ +

Notación de punto

+ +

Arriba, accediste a las propiedades y métodos del objeto usando notación de punto (dot notation). El nombre del objeto (persona) actúa como el espacio de nombre (namespace); al cual se debe ingresar primero para acceder a cualquier elemento encapsulado dentro del objeto. A continuación, escribe un punto y luego el elemento al que deseas acceder: puede ser el nombre de una simple propiedad, un elemento de una propiedad de arreglo o una llamada a uno de los métodos del objeto, por ejemplo:

+ +
persona.edad
+persona.intereses[1]
+persona.bio()
+ +

Espacios de nombres secundarios

+ +

Incluso es posible hacer que el valor de un miembro del objeto sea otro objeto. Por ejemplo, intenta cambiar el miembro nombre de

+ +
nombre: ['Bob', 'Smith'],
+ +

a

+ +
nombre : {
+  pila: 'Bob',
+  apellido: 'Smith'
+},
+ +

Aquí estamos creando efectivamente un espacio de nombre secundario (sub-namespace). Esto suena complejo, pero en realidad no es así: para acceder a estos elementos solo necesitas un paso adicional que es encadenar con otro punto al final. Prueba estos:

+ +
persona.nombre.pila
+persona.nombre.apellido
+ +

Importante: en este punto, también deberás revisar tu código y cambiar cualquier instancia de

+ +
nombre[0]
+nombre[1]
+ +

a

+ +
nombre.pila
+nombre.apellido
+ +

De lo contrario, sus métodos ya no funcionarán.

+ +

Notación de corchetes

+ +

Hay otra manera de acceder a las propiedades del objeto, usando la notación de corchetes. En lugar de usar estos:

+ +
persona.edad
+persona.nombre.pila
+ +

Puedes usar

+ +
persona['edad']
+persona['nombre']['pila']
+ +

Esto se ve muy similar a cómo se accede a los elementos en un arreglo, y básicamente es lo mismo: en lugar de usar un número de índice para seleccionar un elemento, se esta utilizando el nombre asociado con el valor de cada miembro. No es de extrañar que los objetos a veces se denominen arreglos asociativos: asocian cadenas de texto a valores de la misma manera que las arreglos asocian números a valores.

+ +

Establecer miembros de objetos

+ +

Hasta ahora solo hemos buscado recuperar (u obtener) miembros del objeto: también puede establecer (actualizar) el valor de los miembros del objeto simplemente declarando el miembro que deseas establecer (usando la notación de puntos o corchetes), de esta manera:

+ +
persona.edad = 45;
+persona['nombre']['apellido'] = 'Cratchit';
+ +

Intenta ingresar estas líneas y luego vuelve a ver a los miembros para ver cómo han cambiado:

+ +
persona.edad
+persona['nombre']['apellido']
+ +

Establecer miembros no solo es actualizar los valores de las propiedades y métodos existentes; también puedes crear miembros completamente nuevos. Prueba estos:

+ +
persona['ojos'] = 'avellana';
+persona.despedida = function() { alert("¡Adiós a todos!"); }
+ +

Ahora puedes probar a los nuevos miembros:

+ +
persona['ojos']
+person.despedida()
+ +

Un aspecto útil de la notación de corchetes es que se puede usar para establecer dinámicamente no solo los valores de los miembros, sino también los nombres de los miembros. Digamos que queremos que los usuarios puedan almacenar tipos de valores personalizados en sus datos personales, escribiendo el nombre y el valor del miembro en dos entradas de texto. Podríamos obtener esos valores de esta manera:

+ +
var nombrePerzonalizado = entradaNombre.value;
+var valorPerzonalizado = entradaValor.value;
+ +

entonces podríamos agregar este nuevo miembro nombre y valor al objeto persona de esta manera:

+ +
persona[nombrePerzonalizado] = valorPerzonalizado;
+ +

Para probar esto, intenta agregar las siguientes líneas en tu código, justo debajo de la llave de cierre del objeto persona:

+ +
var nombrePerzonalizado = 'altura';
+var valorPerzonalizado = '1.75m';
+persona[nombrePerzonalizado] = valorPerzonalizado;
+ +

Ahora intenta guardar y actualizar, e ingresa lo siguiente en tu entrada de texto:

+ +
persona.altura
+ +

Agregar una propiedad a un objeto no es posible con la notación de puntos, que solo puede aceptar un nombre de miembro literal, no un valor variable que apunte a un nombre.

+ +

¿Qué es "this" (este)?

+ +

Es posible que hayas notado algo un poco extraño en nuestros métodos. Mira esto, por ejemplo:

+ +
saludo: function() {
+  alert('¡Hola!, Soy '+ this.nombre.pila + '.');
+}
+ +

Probablemente te estés preguntando qué es "this". La palabra clave this se refiere al objeto actual en el que se está escribiendo el código, por lo que en este caso this es equivalente a la persona. Entonces, ¿por qué no escribir persona en su lugar? Como verás en el artículo JavaScript orientado a objetos para principiantes cuando comenzaremos a crear constructores, etc., this es muy útil: siempre asegurará que se usen los valores correctos cuando cambie el contexto de un miembro (por ejemplo, dos diferentes instancias de objetos persona) pueden tener diferentes nombres, pero querráx usar su propio nombre al decir su saludo).

+ +

Vamos a ilustrar lo que queremos decir con un par de objetos persona simplificados:

+ +
var persona1 = {
+  nombre: 'Chris',
+  saludo: function() {
+    alert('¡Hola!, Soy '+ this.nombre + '.');
+  }
+}
+
+var persona2 = {
+  nombre: 'Brian',
+  saludo: function() {
+    alert('¡Hola!, Soy '+ this.nombre + '.');
+  }
+}
+ +

En este caso, persona1.saludo() mostrará "¡Hola!, Soy Chris"; persona2.saludo() por otro lado mostrará "¡Hola!, Soy Brian", aunque el código del método es exactamente el mismo en cada caso. Como dijimos antes, this es igual al objeto en el que está el código; esto no es muy útil cuando se escriben objetos literales a mano, pero realmente se vuelve útil cuando se generan objetos dinámicamente (por ejemplo, usando constructores) Todo se aclarará más adelante.

+ +

Has estado usando objetos todo el tiempo

+ +

A medida que has estado repasando estos ejemplos, probablemente hayas pensando que la notación de puntos que has usando es muy familiar. ¡Eso es porque la has estado usando a lo largo del curso! Cada vez que hemos estado trabajando en un ejemplo que utiliza una API de navegador incorporada o un objeto JavaScript, hemos estado usando objetos, porque tales características se crean usando exactamente el mismo tipo de estructuras de objetos que hemos estado viendo aquí, aunque más complejos que nuestros propios ejemplos personalizados.

+ +

Entonces cuando usaste métodos de cadenas de texto como:

+ +
myCadena.split(',');
+ +

Estabas usando un método disponible en una instancia de la clase String. Cada vez que creas una cadena en tu código, esa cadena se crea automáticamente como una instancia de String, y por lo tanto tiene varios métodos/propiedades comunes disponibles en ella.

+ +

Cuando accediste al modelo de objetos del documento (document object model) usando líneas como esta:

+ +
var miDiv = document.createElement('div');
+var miVideo = document.querySelector('video');
+ +

Estaba usando métodos disponibles en una instancia de la clase Document. Para cada página web cargada, se crea una instancia de Document, llamada document, que representa la estructura, el contenido y otras características de la página entera, como su URL. De nuevo, esto significa que tiene varios métodos/propiedades comunes disponibles en él.

+ +

Lo mismo puede decirse de prácticamente cualquier otro Objeto/API incorporado que hayad estado utilizando: Array, Math, etc.

+ +

Ten en cuenta que los Objetos/API incorporados no siempre crean instancias de objetos automáticamente. Como ejemplo, la API de Notificaciones, que permite que los navegadores modernos activen las notificaciones del sistema, requiere que crees una instancia de un nuevo objeto para cada notificación que desees disparar. Intenta ingresar lo siguiente en tu consola de JavaScript:

+ +
var miNotificacion = new Notification('¡Hola!');
+ +

De nuevo, veremos qué son los constructores en un artículo posterior.

+ +
+

Nota: Es útil pensar en la forma en que los objetos se comunican como paso de mensajes — cuando un objeto necesita otro objeto para realizar algún tipo de acción a menudo enviará un mensaje a otro objeto a través de uno de sus métodos, y esperará una respuesta, que conocemos como un valor de retorno.

+
+ +

Resumen

+ +

Enhorabuena, has llegado al final de nuestro primer artículo sobre objetos JS: ahora debes tener una buena idea de cómo trabajar con objetos en JavaScript, incluida la creación de tus propios objetos simples. También debes apreciar que los objetos son muy útiles como estructuras para almacenar datos y funcionalidades relacionadas; si trataras de hacer un seguimiento de todas las propiedades y métodos en nuestro objeto persona como variables y funciones separadas, sería ineficiente y frustrante, y tendríamos el riesgo de chocar con otras variables y funciones que tienen los mismos nombres. Los objetos nos permiten mantener la información segura y protegida en su propio paquete, fuera del peligro.

+ +

En el próximo artículo comenzaremos a ver la teoría de programación orientada a objetos (OOP) y cómo se pueden usar dichas técnicas en JavaScript.

+ +

{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}

diff --git "a/files/es/learn/javascript/objects/ejercicio_pr\303\241ctico_de_construcci\303\263n_de_objetos/index.html" "b/files/es/learn/javascript/objects/ejercicio_pr\303\241ctico_de_construcci\303\263n_de_objetos/index.html" new file mode 100644 index 0000000000..6dfaaf0d08 --- /dev/null +++ "b/files/es/learn/javascript/objects/ejercicio_pr\303\241ctico_de_construcci\303\263n_de_objetos/index.html" @@ -0,0 +1,301 @@ +--- +title: Ejercicio práctico de construcción de objetos +slug: Learn/JavaScript/Objects/Ejercicio_práctico_de_construcción_de_objetos +translation_of: Learn/JavaScript/Objects/Object_building_practice +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}
+ +

En los artículos anteriores se explicó lo fundamental de la teoría de los objetos en JavaScript asi como su sintaxis, para que Usted tenga un punto de partida sólido. En éste artículo, desarrollaremos un ejercicio práctico para ganar experiencia en la programación de objetos en JavaScript, con un resultado divertido y colorido.

+ + + + + + + + + + + + +
Pre-requisitos:Conocimientos básicos de computadores. Entendimiento básico de HTML y CSS. Familiaridad con los conceptos básicos de JavaScript (vea Primeros Pasos con JavaScript y Elementos básicos de JavaScript)  y OOJS (vea Conceptos básicos de los objetos JavaScript).
Objetivos:Ganar experiencia en el uso de objetos y el uso de programación orientada a objetos en un contexto realista.
+ +

Lanzemos algunas pelotas

+ +

Es éste artículo escribiremos un programa demo del juego clásico de pelotas que rebotan para mostrar la gran útilidad de los objetos en JavaScript. En éste demo las pelotas rebotaran en la pantalla y cambiaran de color cuando choquen unas con otras. Así, al final del ejemplo tendremos algo como esto:

+ +

+ +
    +
+ +

En este ejemplo se utilizará Canvas API para dibujar las pelotas en la pantalla y la API requestAnimationFrame para animar todo el contenido de la pantalla. No es necesario que conozca estas funciones previamente. Esperamos que al final de este artículo, quizás pueda estar interesado en explorar su uso y capacidades más en detalle. Durante este desarrollo usaremos objetos y algunas técnicas para hacer que las pelotas puedan rebotar en los bordes y comprobar cuando choquen entre ellas (ésto se conoce como detección de colisiones). 

+ +

Primeros pasos

+ +

Para comenzar haga una copia en su computador de los archivos:  index.html, style.css, y main.js. Estos contienen:

+ +
    +
  1. Un documento HTML sencillo con un elemento <h1>, un elemento <canvas> en el que podamos dibujar los gráficos y otros elementos para aplicar los estilos CSS y el código JavaScript. 
  2. +
  3. Algunos estilos sencillos que servirán para ubicar el elemento <h1>, ocultar la barra de desplazamiento y los margenes del borde de la página (para que luzca mejor).
  4. +
  5. Un archivo JavaScript que sirve para definir el elemento <canvas> y las funciones que vamos a usar.
  6. +
+ +

La primera parte del script es:

+ +
var canvas = document.querySelector('canvas');
+
+var ctx = canvas.getContext('2d');
+
+var width = canvas.width = window.innerWidth;
+var height = canvas.height = window.innerHeight;
+ +

Este script obtiene una referencia del elemento <canvas>, luego llama al método getContext() para definir un contexto en el cual se pueda comenzar a dibujar. La resultado de la variable  (ctx) es el objeto que representa directamente el área de dibujo del <canvas> y permite dibujar elementos 2D en él. 

+ +

A continuación se da valor a las variables width and height que corresponden al ancho y alto del elemento canvas (representado por las propiedades canvas.width y canvas.height), de manera que el alto y ancho coincidan con el alto y ancho del navegador (viewport)  cuyos valores se obtienen directamente de las propiedades window.innerWidth window.innerHeight.

+ +

Puede ver que en el código se encadenan varias asignaciones, para obtener valores más rápidamente. Esto se puede hacer.

+ +

La última parte del script, es la siguiente:

+ +
function random(min, max) {
+  var num = Math.floor(Math.random() * (max - min + 1)) + min;
+  return num;
+}
+ +

Esta función recibe dos números como argumentos de entrada (valor mínimo y maximo) y devuelve un número aleatorio entre ellos.

+ +

Modelando una pelota en nuestro programa

+ +

Nuestro programa tendrá montones de pelotas rebotando por toda la pantalla. Ya que todas las pelotas tendrán el mismo comportamiento, tiene sentido representarlas con un objeto. Empezamos definiendo un constructor para el objeto pelota (Ball), en nuestro código.

+ +
function Ball(x, y, velX, velY, color, size) {
+  this.x = x; //posición horizontal
+  this.y = y; //posición vertical
+  this.velX = velX; //velocidad horizontal
+  this.velY = velY; //velocidad vertical
+  this.color = color; //color
+  this.size = size; //tamaño
+}
+ +

Aquí incluimos algunos parámetros que serán las propiedades que cada pelota necesita para funcionar en nuestro programa: 

+ + + +

Con esto se resuelven las propiedades del objeto, ¿Pero qué hacemos con los métodos? Ya que queremos que las pelotas realicen algo en nuestro programa. 

+ +

Dibujando las pelotas

+ +

Para dibujar, añadiremos el siguiente método draw() al prototipo del objeto Ball():

+ +
Ball.prototype.draw = function() {
+  ctx.beginPath();
+  ctx.fillStyle = this.color;
+  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+  ctx.fill();
+}
+ +

Con esta función cada objeto pelota Ball() puede dibujarse en la pantalla utilizando el contexto 2D definido anteriormente (ctx)  

+ + + +

Ya se puede empezar a testear el objeto.

+ +
    +
  1. Guarde el código hasta ahora, y cargue el archivo HTML en un navegador.
  2. +
  3. Abra la consola de JavaScript en el navegador, y refresque la página, para que el tamaño del canvas modifique sus dimensiones adaptándose al viewport con la consola abierta. 
  4. +
  5. Teclee lo siguiente en la consola para crear una nueva pelota. +
    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
    +
  6. +
  7. Pruebe a llamar a las variables miembro: +
    testBall.x
    +testBall.size
    +testBall.color
    +testBall.draw()
    +
  8. +
  9. Al teclear la última línea, debería ver que la pelota se dibuja en alguna parte del canvas
  10. +
+ +

Actualizando los datos de la pelota

+ +

Ahora podemos dibujar una pelota en una posición dada, pero para empezar a moverla, se necesita una función de actualización de algún tipo. Podemos añadir el código a continuación, al final del archivo de JavaScript, para añidir un método de actualización update() en el prototipo de la clase Ball()

+ +
Ball.prototype.update = function() {
+  if ((this.x + this.size) >= width) {
+    this.velX = -(this.velX);
+  }
+
+  if ((this.x - this.size) <= 0) {
+    this.velX = -(this.velX);
+  }
+
+  if ((this.y + this.size) >= height) {
+    this.velY = -(this.velY);
+  }
+
+  if ((this.y - this.size) <= 0) {
+    this.velY = -(this.velY);
+  }
+
+  this.x += this.velX;
+  this.y += this.velY;
+}
+ +

Las cuatro primeras partes de la función verifican si la pelota a alcanzado el borde del canvas. Si es así, se invierte la dirección de la velocidad, para que la pelota se mueva en la dirección contraria. Así, si la pelota va hacia arriba, (velY positiva) , entonces la velocidad vertical es cambiada, para que se mueva hacia abajo (velY negativa).

+ +

Los cuatro posibles casos son: 

+ + + +

En cada caso, se ha tenido en cuenta el tamaño (size) de la pelota en los cálculos, ya que las coordenadas x e y corresponden al centro de la pelota, pero lo que queremos ver es el borde de la pelota cuando choca con el perímetro del canvas — que la pelota rebote, cuando está a medio camino fuera de el —.

+ +

Las dos últimas líneas de código, suman  la velocidad en x (velX) al valor de la coordenada x  , y el valor de la velocidad en y (velY)  a la coordenada y —  con esto se consigue el efecto de que la pelota se mueva cada vez que este método es llamado. 

+ +

Llegados a este punto: ¡continuemos, con las animaciones!

+ +

Animando las pelotas

+ +

Hagamos esto divertido! Ahora vamos a empezar a añadir pelotas al canvas, y animándolas.

+ +

1. Primero, necesitamos algún sitio donde guardas las pelotas. El siguiente arreglo hará esta función — añádela al final de tu código. 

+ +
var balls = [];
+ +

Todos los programas que generan animaciones normalmente tienen un bucle de animación, que sirve para actualizar los datos del programa, para entonces generar la imagen correspondiente; esta es la estrategia básica para la mayor parte de juegos y programas similares. 

+ +

2. Añadamos las siguientes instrucciones al final del código: 

+ +
function loop() {
+  ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
+  ctx.fillRect(0, 0, width, height);
+
+  while (balls.length < 25) {
+    var size = random(10,20);
+    var ball = new Ball(
+      // la posición de las pelotas, se dibujará al menos siempre
+      // como mínimo a un ancho de la pelota de distancia al borde del
+      // canvas, para evitar errores en el dibujo
+      random(0 + size,width - size),
+      random(0 + size,height - size),
+      random(-7,7),
+      random(-7,7),
+      'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
+      size
+    );
+    balls.push(ball);
+  }
+
+  for (var i = 0; i < balls.length; i++) {
+    balls[i].draw();
+    balls[i].update();
+  }
+
+  requestAnimationFrame(loop);
+}
+ +

Nuestra función de bucle: loop(), hace lo siguiente: 

+ + + +

3. Por último, pero no menos importante, añadimos la siguiente línea, al final del código.-- es necesario llamar a la función inicialmente para que la animación comience. 

+ +
loop();
+ +

Eso es todo para la parte básica — pruebe a guardar el código y refrescar el navegador para comprobar si aparecen las pelotas rebotando!

+ +

Añadiendo la detección de colisiones

+ +

Ahora, un poco de diversión, añadamos la detección de colisiones a nuestro código. Así las pelotas, sabrán cuando chocan unas contra otras.

+ +
    +
  1. El primer paso, será añadir el código a continuación a continuación de donde se definió el método  update(). (en código de Ball.prototype.update) + +
    Ball.prototype.collisionDetect = function() {
    +  for (var j = 0; j < balls.length; j++) {
    +    if (!(this === balls[j])) {
    +      var dx = this.x - balls[j].x;
    +      var dy = this.y - balls[j].y;
    +      var distance = Math.sqrt(dx * dx + dy * dy);
    +
    +      if (distance < this.size + balls[j].size) {
    +        balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
    +      }
    +    }
    +  }
    +}
    + +

    Esta función es un poco complicada, así que no hay que preocuparse mucho si de momento no se comprende del todo.  

    + +
      +
    • Para cada pelota, necesitamos comprobar si chocará con cada una de las otras pelotas. Para esto, en un bucle for para recorrer todas las pelotas.
    • +
    • Dentro del bucle, usamos un if  para comprobar si la pelota que estamos mirando en ese ciclo del bucle for es la pelota que estamos mirando. No queremos mirar si una pelota ha chocado consigo misma. Para esto miramos si la pelota actual (es decir la pelota que está invocando al método que resuelve la detección de colisiones) es la misma que la indicada por el bucle. Usamos un operador ! para indicar una negación en la comparación, así que el código dentro de la condición  solo se ejecuta si estamos mirando dos pelotas distintas.
    • +
    • Usamos un algoritmo común para comprobar la colisión de los dos pelotas. Básicamente miramos si el área de dos círculos se superponen.  Esto se explica mejor en el enlace detección de colision 2D.
    • +
    • En este caso, únicamente se define la propiedad de color para las dos pelotas, cambiándolas a un nuevo color aleatorio. Se podría haber hecho cosas más complicadas, como que las pelotas rebotasen una con la otra de forma realista, pero esto habría supuesto un desarrollo más complejo. Para desarrollar esos efectos de simulación física, los desarrolladores tienden a usar librerías de física como PhysicsJS, matter.js, Phaser, etc.
    • +
    +
  2. +
  3. También es necesario llamar este método en cada instante de la animación. balls[i].update(); en la línea: +
    balls[i].collisionDetect();
    +
  4. +
  5. Guardar y refrescar la demo de nuevo y podrá ver como las pelotas cambian de color cuando chocan entre ellas.
  6. +
+ +
+

Nota: Si tiene problemas para hacer funcionar este ejemplo, puede comparar su código JavaScript, con el código de la version_final (y también ver como funciona al ejecutarla).

+
+ +

Resumen

+ +

Esperamos que se haya divertido escribiendo su propio mundo de pelotas que chocan aleatoriamente, usando objetos y programación orientada a objetos. Esto debería haberle dado una práctica útil y haber sido un buen ejemplo. 

+ +

Lea también

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/javascript/objects/index.html b/files/es/learn/javascript/objects/index.html new file mode 100644 index 0000000000..191d23bc9f --- /dev/null +++ b/files/es/learn/javascript/objects/index.html @@ -0,0 +1,67 @@ +--- +title: Introducción a los objetos JavaScript +slug: Learn/JavaScript/Objects +tags: + - Aprender + - Artículo + - Assessment + - CodingScripting + - Evaluación + - Guía + - JavaScript + - Objetos + - Principiante + - TopicStub + - Tutorial +translation_of: Learn/JavaScript/Objects +--- +
{{LearnSidebar}}
+ +

En JavaScript, la mayoría de las cosas son objetos, desde características del núcleo de JavaScript como arrays hasta el explorador {{Glossary("API", "APIs")}} construído sobre JavaScript. Incluso puedes crear tus propios objetos para encapsular funciones y variables relacionadas dentro de paquetes eficientes que actúan como prácticos contenedores de datos. La naturaleza de JavaScript basada-en-objetos es importante de entender, si quieres avanzar con tu conocimiento del lenguaje, y por ello hemos hecho este módulo para ayudarte. Aquí enseñamos teoría de objetos y sintaxis en detalle, y luego veremos como crear tus propios objetos.

+ +

¿Buscas convertirte en desarrollador web de front-end?

+ +

Hemos puesto un curso que incluye toda la información esencial que necesitas para alcanzar esa meta

+ +

Comienza aquí

+ +

Prerrequisitos

+ +

Antes de empezar este módulo deberías estar familiarizado con  {{Glossary("HTML")}} and {{Glossary("CSS")}}. Te aconsejamos trabajar los módulos Introducción a HTML y Introducción a CSS antes de empezar con JavaScript.

+ +

También deberías conocer lo básico de Javascript antes de entrar en detalle en los objetos de Javascript. Antes de empezar este módulo, revisa Primeros pasos con JavaScript y Elementos básicos de Java​Script.

+ +
+

Nota: Si trabajas en un ordenador, tablet u otro dispositivo donde no puedas editar tus propios ficheros, prueba a ejecutar los ejemplos de código online en páginas como JSBin o Thimble.

+
+ +

Guías

+ +
+
Principios básicos de los Objetos
+
En este primer artículo sobre los objetos en Javascript, aprenderemos los fundamentos de la sintaxis de objetos en Javascript y revisaremos algunas características ya vistas anteriormente en el curso, remarcando el hecho que muchas de ellas son en realidad objetos.
+
JavaScript Orientado a Objetos para principiantes
+
Una vez vistos los principios básicos, nos centraremos en JavaScript orientado a objetos (OOJS) — este artículo presenta los elementos básicos de la teoría de programación orientada a objetos (OOP), posteriormente explora la manera en que JavaScript emula las clases de un objeto a través de los constructores de funciones, y cómo crea las instancias de un objeto.
+
Prototipos de Objetos
+
Los prototipos son el mecanismo por el cual los objetos en JavaScript heredan caraterísticas entre sí, y funcionan de manera distinta a los mecanismos de herencia  de los lenguages de programación orientada a objetos clásicos.
+
Herencia en JavaScript
+
Con la mayoría de los detalles sangrientos de OOJS ahora explicados, este artículo muestra cómo crear clases de objetos "hijo" (constructores) que heredan características de sus clases "principales". Además, presentamos algunos consejos sobre cuándo y dónde puede usar OOJS.
+
Trabajando con datos JSON
+
La notación de objetos JavaScript (JSON) es un formato estándar basado en texto para representar datos estructurados basados en la sintaxis de objetos de JavaScript, que se usa comúnmente para representar y transmitir datos en sitios web (es decir, enviar datos desde el servidor al cliente; se mostrará en una página web). Lo encontrarás con bastante frecuencia, por lo que en este artículo te proporcionamos todo lo que necesitas para trabajar con JSON mediante JavaScript, incluido el análisis del JSON para que puedas acceder a los elementos de datos y escribir su propio JSON.
+
Práctica de Construcción de Objetos
+
En artículos anteriores vimos toda la teoría esencial de los objetos de JavaScript y los detalles de sintaxis, brindándote una base sólida para comenzar. En este artículo nos sumergimos en un ejercicio práctico, que te dará más práctica en la construcción de objetos personalizados de JavaScript, que producen algo divertido y colorido: algunas pelotas de colores rebotando.
+
+ +

Evaluaciones

+ +
+
Agregar funciones a nuestra demo de "Pelotas Rebotando"
+
En esta evaluación, se espera que utilices la demostración de pelotas que rebotan del artículo anterior como punto de partida y que le agregues algunas características nuevas e interesantes.
+
+ +

Vea también

+ +
+
Aprender JavaScript
+
Un excelente recurso para los aspirantes a desarrolladores web —prenda JavaScript en un entorno interactivo, con lecciones cortas y pruebas interactivas, guiado por una evaluación automatizada. Las primeras 40 lecciones son gratuitas, y el curso completo está disponible por un pequeño pago único.
+
diff --git a/files/es/learn/javascript/objects/inheritance/index.html b/files/es/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..e1cbba42da --- /dev/null +++ b/files/es/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,400 @@ +--- +title: Herencia en JavaScript +slug: Learn/JavaScript/Objects/Inheritance +translation_of: Learn/JavaScript/Objects/Inheritance +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}
+ +

Con la mayoría de los detalles internos de OOJS (JavaScript Orientado a Objetos) explicados, este artículo muestra cómo crear clases "hijo" (constructores) que heredan características de sus clases "padre". Además, presentamos algunos consejos sobre cuándo y dónde puedes usar OOJS y cómo se crean las clases con la sintaxis moderna de ECMAScript.

+ + + + + + + + + + + + +
Pre-requisitos:Conocimientos básicos de informática, una comprensión básica de HTML y CSS, familiaridad con los principios básicos de JavaScript (ver Primeros pasos y Construyendo bloques) y conceptos básicos de OOJS (ver Introduccion a objetos).
Objetivo:Entender cómo es posible implementar la herencia en JavaScript.
+ +

Herencia prototípica

+ +

Hasta ahora hemos visto algo de herencia en acción — hemos visto cómo funcionan las cadenas de prototipos, y cómo los miembros son heredados subiendo una cadena. Pero principalmente esto ha involucrado funciones integradas del navegador. ¿Cómo creamos un objeto en JavaScript que hereda de otro objeto?

+ +

Exploremos cómo hacer esto con un ejemplo concreto.

+ +

Primeros pasos

+ +

Primero que nada, hazte una copia local de nuestro archivo  oojs-class-inheritance-start.html (míralo corriendo en vivo también). Dentro de aquí encontrarás el mismo ejemplo de constructor de Persona() que hemos estado usando a través del módulo, con una ligera diferencia — hemos definido solo las propiedades dentro del constructor:

+ +
function Persona(nombrePila, apellido, edad, genero, intereses) {
+  this.nombre = {
+    nombrePila,
+    apellido
+  };
+  this.edad = edad;
+  this.genero = genero;
+  this.intereses = intereses;
+};
+ +

Todos los métodos están definidos en el prototipo del constructor. Por ejemplo:

+ +
Persona.prototype.saludo = function() {
+  alert('¡Hola! soy ' + this.nombre.nombrePila + '.');
+};
+ +
+

Nota: En el código fuente, también verá los métodos bio() y despedida() definidos. Más tarde verá cómo estos pueden ser heredados por otros constructores.

+
+ +

Digamos que quisieramos crear una clase de Profesor, como la que describimos en nuestra definición inicial orientada a objetos, que hereda todos los miembros de Persona, pero también incluye:

+ +
    +
  1. Una nueva propiedad, materia — esto contendrá la materia que el profesor enseña.
  2. +
  3. Un método actualizado de saludo(), que suena un poco más formal que el método estándar de saludo() — más adecuado para un profesor que se dirige a algunos estudiantes en la escuela.
  4. +
+ +

Definiendo un constructor Profesor()

+ +

Lo primero que tenemos que hacer es crear el constructor Profesor()  — añadimos lo siguiente tras el código existente:

+ +
function Profesor(nombrePila, apellido, edad, genero, intereses, materia) {
+  Person.call(this, nombrePila, apellido, edad, genero, intereses);
+
+  this.materia = materia;
+}
+ +

Esto es similar al constructor de Persona en muchos aspectos, pero hay algo extraño aquí que no hemos visto antes: la función call (). Esta función básicamente le permite llamar a una función definida en otro lugar, pero en el contexto actual.
+ El primer parámetro especifica el valor de this que desea utilizar al ejecutar la función, y los otros parámetros son aquellos que deben pasarse a la función cuando se invoca.

+ +

Queremos que el constructor Profesor() tome los mismos parámetros que el constructor Persona() del que está heredando, por lo que los especificamos todos como parámetros en la invocación call().

+ +

La última línea dentro del constructor simplemente define la nueva propiedad subject que los profesores tendrán y que las personas genéricas no tienen.

+ +

Como nota, podríamos haber simplemente hecho esto:

+ +
function Profesor(nombrePila, apellido, edad, genero, intereses, materia) {
+  this.nombre = {
+    nombrePila,
+    apellido
+  };
+  this.edad = edad;
+  this.genero = genero;
+  this.intereses = intereses;
+  this.materia = materia;
+}
+ +

Pero esto es solo definir las propiedades de nuevo, no heredarlas de Persona(), por lo que anula el punto de lo que estamos tratando de hacer. También lleva más líneas de código.

+ +

Heredando de un constructor sin parámetros

+ +

Nótese que si el constructor del cual se está heredando no toma los valores de sus propiedades de parámetros, no se necesita especificarlos como argumentos adicionales en call(). Por ejemplo, si se tuviera algo muy simple como esto:

+ +
function Brick() {
+  this.width = 10;
+  this.height = 20;
+}
+ +

Se podrían heredar las propiedades width y height haciendo esto (así como los otros pasos descritos a continuación, por supuesto):

+ +
function BlueGlassBrick() {
+  Brick.call(this);
+
+  this.opacity = 0.5;
+  this.color = 'blue';
+}
+ +

Nótese que solo especificamos this dentro de call() — no se requieren otros parámetros ya que no estamos heredando ninguna propiedad del padre que sea establecida por parámetros.

+ +

Estableciendo el prototipo de Profesor() y su referencia al constructor

+ +

Todo va bien hasta ahora, pero tenemos un problema. Definimos un nuevo constructor, y tiene una propiedad prototype, la cual por defecto solo contiene una referencia a la función constructor en sí misma. No contiene los métodos de la propiedad prototype del constructor Persona. Para ver esto, introduzca Object.getOwnPropertyNames(Profesor.prototype) ya sea en el campo de texto o en la consola de Javascript . Introdúzcalo nuevamente, reemplazando Profesor con Persona. El nuevo constructor tampoco hereda esos métodos. Para ver esto, compare los resultados de Persona.prototype.saludo and Profesor.prototype.saludo. Necesitamos obtener Profesor() para obtener los métodos definidos en el prototipo de Persona(). ¿Cómo lo hacemos?

+ +
    +
  1. Añade la siguiente línea debajo de tu adición anterior: +
    Profesor.prototype = Object.create(Persona.prototype);
    + Aquí es cuando nuestro amigo create() sale al rescate de nuevo. En este caso lo estamos usando para crear un nuevo objeto y hacerlo el valor de Profesor.prototype. El nuevo objeto tiene Persona.prototype como su prototipo y por lo tanto heredará, si y cuando lo necesite, todos los métodos disponibles en Persona.prototype.
  2. +
  3. Necesitamos hacer una cosa más antes de proseguir. Después de agregar la última línea, la propiedad constructor de  Profesor.prototype es ahora igual a Persona(), debido a que acabamos de asignar Profesor.prototype para que haga referencia a un objeto que hereda sus propiedades de Persona.prototype! Ahora prueba guardando tu código, carga la página en un explorador e intenta verificar en la consola el valor de  Profesor.prototype.constructor.
  4. +
  5. Esto puede volverse un problema, así que necesitamos corregirlo. Puedes hacerlo regresando a tu código y agregando la siguiente línea al final: +
    Profesor.prototype.constructor = Profesor;
    +
  6. +
  7. Ahora, si guardas y actualizas, el valor de Profesor.prototype.constructor debe regresar Profesor(), como se espera, además de que ahora estamos heredando de Persona()!
  8. +
+ +

Dándole a Profesor() un nuevo método saludo()

+ +

Para finalizar nuestro código, necesitamos definir un nuevo método saludo() en el constructor de Profesor().

+ +

La manera más fácil es definirlo en el prototipo de Profesor() — agrega lo siguiente al final de tu código:

+ +
Profesor.prototype.saludo = function() {
+  var prefijo;
+
+  if (this.genero === 'masculino' || this.genero === 'Masculino' || this.genero === 'm' || this.genero === 'M') {
+    prefijo = 'Sr.';
+  } else if (this.genero === 'female' || this.genero === 'Femenino' || this.genero === 'f' || this.genero === 'F') {
+    prefijo = 'Sra.';
+  } else {
+    prefijo = 'Sx.';
+  }
+
+  alert('Hola. Mi nombre es ' + prefijo + ' ' + this.nombre.apellido + ', y enseño ' + this.materia + '.');
+};
+ +

Esto muestra el saludo del profesor, el cual además utiliza un prefijo apropiado para su género, resuelto utilizando un bloque else-if.

+ +

Probando el ejemplo

+ +

Ahora que ha ingresado todo el código, intente creando una instancia de objeto desde Profesor() poniendo lo que sigue al final de su archivo (o algo similar a su elección):

+ +
var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
+ +

Ahora guarde y actualice, e intente accediendo a las propiedades y metodos de su nuevo teacher1 objecto, por ejemplo:

+ +
teacher1.name.first;
+teacher1.interests[0];
+teacher1.bio();
+teacher1.subject;
+teacher1.greeting();
+teacher1.farewell();
+ +

Esto deberia trabajar bien. Las consultas de las líneas 1, 2, 3, y 6 acceden a miembros heredados del genérico Person() constructor (clase). La consulta de la línea 4 accede un miembro que es disponible solamente en el mas especializado Teacher() constructor (clase). La consulta de la línea 5 accedería a un miembro desde Person(), excepto por el hecho que Teacher() tiene sus propios miembros con el mismo nombre, entonces la consulta accede a ese miembro.

+ +
+

Nota: Si tiene problemas con el funcionamiento, compare su código con nuestra versión final (vea corriendo en vivo también).

+
+ +

La técnica que mostramos aquí no es la única para crear herencia de clases en JavaScript, pero funciona OK, y le dá una buena idea acerca de cómo implementar herencia en JavaScript.

+ +

También estará interesado en verificar algo de las nuevas características de {{glossary("ECMAScript")}} que nos permiten hacer herencia mas claramente en JavaScript (véase Classes). No se cubrió todo aquí, como tampoco es soportado aún por todos los navegadores. Todo el otro código de constructores que se discutió aquí en estos artículos son soportados por IE9 o superior, y hay caminos para lograr superiores soportes que estos.

+ +

Un simple camino es usar una librería de JavaScript — la mayoría de las opciones mas populares tienen un facil ajuste de funcionalidad disponible para hacer herencia mas facil y rápido. CoffeeScript por ejemplo provee class, extends, etc.

+ +

Un ejercicio mas allá

+ +

En nuestra Sección teórica de POO, también incluimos una clase Student como un concepto, el cual hereda todas las características de Person, y también tiene un método diferende de greeting() que Person que es mas informal que el saludo de los profesores Teacher. Dele una mirada al saludo de los estudiantes, y trate de implementar su propio constructor de saludo Student() que herede todas las características de Person(), e implemente las diferentes funciones de saludo greeting().

+ +
+

Nota: Si tiene problemas resolviendo esto, dele una mirada a nuestra versión final (véala tambien funcionando ).

+
+ +

Resúmen de miembros objeto

+ +

To summarize, you've basically got three types of property/method to worry about:

+ +
    +
  1. Those defined inside a constructor function that are given to object instances. These are fairly easy to spot — in your own custom code, they are the members defined inside a constructor using the this.x = x type lines; in built in browser code, they are the members only available to object instances (usually created by calling a constructor using the new keyword, e.g. var myInstance = new myConstructor()).
  2. +
  3. Those defined directly on the constructor themselves, that are available only on the constructor. These are commonly only available on built-in browser objects, and are recognized by being chained directly onto a constructor, not an instance. For example, Object.keys().
  4. +
  5. Those defined on a constructor's prototype, which are inherited by all instances and inheriting object classes. These include any member defined on a Constructor's prototype property, e.g. myConstructor.prototype.x().
  6. +
+ +

If you are not sure which is which, don't worry about it just yet — you are still learning, and familiarity will come with practice.

+ +

ECMAScript 2015 Classes

+ +

ECMAScript 2015 introduces class syntax to JavaScript as a way to write reusable classes using easier, cleaner syntax, which is more similar to classes in C++ or Java. In this section we'll convert the Person and Teacher examples from prototypal inheritance to classes, to show you how it's done.

+ +
+

Note: This modern way of writing classes is supported in all modern browsers, but it is still worth knowing about how the underlying prototypal inheritance in case you work on a project that requires supporting a browser that doesn't support this syntax (most notably Internet Explorer).

+
+ +

Let's look at a rewritten version of the Person example, class-style:

+ +
class Person {
+  constructor(first, last, age, gender, interests) {
+    this.name = {
+      first,
+      last
+    };
+    this.age = age;
+    this.gender = gender;
+    this.interests = interests;
+  }
+
+  greeting() {
+    console.log(`Hi! I'm ${this.name.first}`);
+  };
+
+  farewell() {
+    console.log(`${this.name.first} has left the building. Bye for now!`);
+  };
+}
+
+ +

The class statement indicates that we are creating a new class. Inside this block, we define all the features of the class:

+ + + +

We can now instantiate object instances using the new operator, in just the same way as we did before:

+ +
let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
+han.greeting();
+// Hi! I'm Han
+
+let leia = new Person('Leia', 'Organa', 19, 'female' ['Government']]);
+leia.farewell();
+// Leia has left the building. Bye for now
+
+ +
+

Note: Under the hood, your classes are being converted into prototypal Inheritance models — this is just syntactic sugar. But I'm sure you'll agree that it's easier to write.

+
+ +

Inheritance with class syntax

+ +

Above we created a class to represent a person. They have a series of attributes that are common to all people; in this section we'll create our specialized Teacher class, making it inherit from Person using modern class syntax. This is called creating a subclass or subclassing.

+ +

To create a subclass we use the extends keyword to tell JavaScript the class we want to base our class on.

+ +
class Teacher extends Person {
+  constructor(first, last, age, gender, interests, subject, grade) {
+    this.name = {
+      first,
+      last
+    };
+
+  this.age = age;
+  this.gender = gender;
+  this.interests = interests;
+  // subject and grade are specific to Teacher
+  this.subject = subject;
+  this.grade = grade;
+  }
+}
+ +

We can make the code more readable by defining the super() operator as the first item inside the constructor(). This will call the parent class' constructor, and inherit the members we specify as parameters of super(), as long as they are defined there:

+ +
class Teacher extends Person {
+  constructor(first, last, age, gender, interests, subject, grade) {
+    super(first, last, age, gender, interests);
+
+    // subject and grade are specific to Teacher
+    this.subject = subject;
+    this.grade = grade;
+  }
+}
+
+ +

When we instantiate Teacher object instances, we can now call methods and properties defined on both Teacher and Person, as we'd expect:

+ +
let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
+snape.greeting(); // Hi! I'm Severus.
+snape.farewell(); // Severus has left the building. Bye for now.
+snape.age // 58
+snape.subject; // Dark arts
+
+ +

Like we did with Teachers, we could create other subclasses of Person to make them more specialized without modifying the base class.

+ +
+

Note: You can find this example on GitHub as es2015-class-inheritance.html (see it live also).

+
+ +

Getters and Setters

+ +

There may be times when we want to change the values of an attribute in the classes we create or we don't know what the final value of an attribute will be. Using the Teacher example, we may not know what subject the teacher will teach before we create them, or their subject may change between terms.

+ +

We can handle such situations with getters and setters.

+ +

Let's enhance the Teacher class with getters and setters. The class starts the same as it was the last time we looked at it.

+ +

Getters and setters work in pairs. A getter returns the current value of the variable and its corresponding setter changes the value of the variable to the one it defines.

+ +

The modified Teacher class looks like this:

+ +
class Teacher extends Person {
+  constructor(first, last, age, gender, interests, subject, grade) {
+    super(first, last, age, gender, interests);
+    // subject and grade are specific to Teacher
+    this._subject = subject;
+    this.grade = grade;
+  }
+
+  get subject() {
+    return this._subject;
+  }
+
+  set subject(newSubject) {
+    this._subject = newSubject;
+  }
+}
+
+ +

In our class above we have a getter and setter for the subject property. We use _  to create a separate value in which to store our name property. Without using this convention, we would get errors every time we called get or set. At this point:

+ + + +

The example below shows the two features in action:

+ +
// Check the default value
+console.log(snape.subject) // Returns "Dark arts"
+
+// Change the value
+snape.subject="Balloon animals" // Sets _subject to "Balloon animals"
+
+// Check it again and see if it matches the new value
+console.log(snape.subject) // Returns "Balloon animals"
+
+ +
+

Note: You can find this example on GitHub as es2015-getters-setters.html (see it live also).

+
+ +

When would you use inheritance in JavaScript?

+ +

Particularly after this last article, you might be thinking "woo, this is complicated". Well, you are right. Prototypes and inheritance represent some of the most complex aspects of JavaScript, but a lot of JavaScript's power and flexibility comes from its object structure and inheritance, and it is worth understanding how it works.

+ +

In a way, you use inheritance all the time. Whenever you use various features of a Web API , or methods/properties defined on a built-in browser object that you call on your strings, arrays, etc., you are implicitly using inheritance.

+ +

In terms of using inheritance in your own code, you probably won't use it often, especially to begin with, and in small projects. It is a waste of time to use objects and inheritance just for the sake of it when you don't need them. But as your code bases get larger, you are more likely to find a need for it. If you find yourself starting to create a number of objects that have similar features, then creating a generic object type to contain all the shared functionality and inheriting those features in more specialized object types can be convenient and useful.

+ +
+

Note: Because of the way JavaScript works, with the prototype chain, etc., the sharing of functionality between objects is often called delegation. Specialized objects delegate functionality to a generic object type.

+
+ +

When using inheritance, you are advised to not have too many levels of inheritance, and to keep careful track of where you define your methods and properties. It is possible to start writing code that temporarily modifies the prototypes of built-in browser objects, but you should not do this unless you have a really good reason. Too much inheritance can lead to endless confusion, and endless pain when you try to debug such code.

+ +

Ultimately, objects are just another form of code reuse, like functions or loops, with their own specific roles and advantages. If you find yourself creating a bunch of related variables and functions and want to track them all together and package them neatly, an object is a good idea. Objects are also very useful when you want to pass a collection of data from one place to another. Both of these things can be achieved without use of constructors or inheritance. If you only need a single instance of an object, then you are probably better off just using an object literal, and you certainly don't need inheritance.

+ +

Alternativas para extender la cadena del prototipos

+ +

En JavaScript, hay varias maneras diferentes de extender el prototipo de un objeto aparte de lo que hemos mostrado anteriormente. Para saber más sobre las otras formas, visite nuestro artículo Herencia y la cadena de prototipos.

+ +

Resumen

+ +

Este artículo ha cubierto el resto de la teoría y sintaxis central de OOJS que creemos que debería conocer ahora. En este punto debe entender los conceptos básicos de objetos JavaScript y POO, prototipos y herencia de prototipos, cómo crear clases (constructores) e instancias de objetos, añadir características a las clases y crear subclases que heredan de otras clases.

+ +

En el siguiente artículo veremos cómo trabajar con JavaScript Object Notation (JSON), un formato común de intercambio de datos escrito con objetos JavaScript.

+ +

Véase también

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}

+ +

En éste módulo

+ + diff --git a/files/es/learn/javascript/objects/json/index.html b/files/es/learn/javascript/objects/json/index.html new file mode 100644 index 0000000000..09009165cf --- /dev/null +++ b/files/es/learn/javascript/objects/json/index.html @@ -0,0 +1,339 @@ +--- +title: Trabajando con JSON +slug: Learn/JavaScript/Objects/JSON +tags: + - Arreglos + - Artículo + - Guía + - JSON + - Objetos + - Parsing + - Principiante + - Stringifying + - Tutorial +translation_of: Learn/JavaScript/Objects/JSON +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}
+ +

JavaScript Object Notation (JSON) es un formato basado en texto estándar para representar datos estructurados en la sintaxis de objetos de JavaScript. Es comúnmente utilizado para transmitir datos en aplicaciones web (por ejemplo: enviar algunos datos desde el servidor al cliente, así estos datos pueden ser mostrados en páginas web, o vice versa). Se enfrentará a menudo con él, así que este artículo le entrega todo lo que necesita saber para trabajar con JSON utilizando JavaScript, incluyendo el análisis JSON para acceder a los datos en su interior, y cómo crear JSON.

+ + + + + + + + + + + + +
Prerrequisitos:Alfabetismo computacional básico, una comprensión básica de HTML y CSS, familiaridad con los temas básicos de JavaScript (vea First steps y Building blocks) y OOJS básico (vea Introduction to objects).
Objetivo:Entender cómo trabajar con datos almacenados en JSON, y crear objetos JSON propios.
+ +

¿Qué es realmente JSON?

+ +

{{glossary("JSON")}} es un formato de datos basado en texto que sigue la sintaxis de objeto de JavaScript, popularizado por Douglas Crockford. Aunque es muy parecido a la sintaxis de objeto literal de JavaScript, puede ser utilizado independientemente de JavaScript, y muchos entornos de programación poseen la capacidad de leer (convertir; parsear) y generar JSON.

+ +

Los JSON son cadenas - útiles cuando se quiere transmitir datos a través de una red. Debe ser convertido a un objeto nativo de JavaScript cuando se requiera acceder a sus datos. Ésto no es un problema, dado que JavaScript posee un objeto global JSON que tiene los métodos disponibles para convertir entre ellos.

+ +
+

Nota: Convertir una cadena a un objeto nativo se denomina parsing, mientras que convertir un objeto nativo a una cadena para que pueda ser transferido a través de la red se denomina stringification.

+
+ +

Un objeto JSON puede ser almacenado en su propio archivo, que es básicamente sólo un archivo de texto con una extension .json, y una {{glossary("MIME type")}} de application/json.

+ +

Estructura del JSON

+ +

Como se describió previamente, un JSON es una cadena cuyo formato recuerda al de los objetos literales JavaScript. Es posible incluir los mismos tipos de datos básicos dentro de un JSON que en un objeto estándar de JavaScript - cadenas, números, arreglos, booleanos, y otros literales de objeto. Esto permite construir una jerarquía de datos, como ésta:

+ +
{
+  "squadName": "Super hero squad",
+  "homeTown": "Metro City",
+  "formed": 2016,
+  "secretBase": "Super tower",
+  "active": true,
+  "members": [
+    {
+      "name": "Molecule Man",
+      "age": 29,
+      "secretIdentity": "Dan Jukes",
+      "powers": [
+        "Radiation resistance",
+        "Turning tiny",
+        "Radiation blast"
+      ]
+    },
+    {
+      "name": "Madame Uppercut",
+      "age": 39,
+      "secretIdentity": "Jane Wilson",
+      "powers": [
+        "Million tonne punch",
+        "Damage resistance",
+        "Superhuman reflexes"
+      ]
+    },
+    {
+      "name": "Eternal Flame",
+      "age": 1000000,
+      "secretIdentity": "Unknown",
+      "powers": [
+        "Immortality",
+        "Heat Immunity",
+        "Inferno",
+        "Teleportation",
+        "Interdimensional travel"
+      ]
+    }
+  ]
+}
+ +

Si se carga este objeto en un programa de JavaScript, convertido (parseado) en una variable llamada superHeroes por ejemplo, se podría acceder a los datos que contiene utilizando la misma notación de punto/corchete que se revisó en el artículo JavaScript object basics. Por ejemplo:

+ +
superHeroes.homeTown
+superHeroes['active']
+ +

Para acceder a los datos que se encuentran más abajo en la jerarquía, simplemente se debe concatenar los nombres de las propiedades y los índices de arreglo requeridos. Por ejemplo, para acceder al tercer superpoder del segundo héroe registrado en la lista de miembros, se debería hacer esto: 

+ +
superHeroes['members'][1]['powers'][2]
+ +
    +
  1. Primero el nombre de la variable — superHeroes.
  2. +
  3. Dentro de esta variable para acceder a la propiedad members utilizamos ["members"].
  4. +
  5. members contiene un arreglo poblado por objetos. Para acceder al segundo objeto dentro de este arreglo se utiliza [1].
  6. +
  7. Dentro de este objeto, para acceder a la propiedad powers utilizamos ["powers"].
  8. +
  9. Dentro de la propiedad powers existe un arreglo que contiene los superpoderes del héroe seleccionado. Para acceder al tercer superpoder se utiliza [2].
  10. +
+ +
+

Nota: El JSON previamente visto se encuentra disponible dentro de una variable en el ejemplo JSONTest.html (vea el código fuente). Intente cargarlo y luego acceder a los datos contenidos en la variable por medio de la consola JavaScript de su navegador.

+
+ +

Arreglos como JSON

+ +

Anteriormente se mencionó que el texto JSON básicamente se parece a un objeto JavaScript, y esto es en gran parte cierto. La razón de esto es que un arreglo es también un JSON válido, por ejemplo:

+ +
[
+  {
+    "name": "Molecule Man",
+    "age": 29,
+    "secretIdentity": "Dan Jukes",
+    "powers": [
+      "Radiation resistance",
+      "Turning tiny",
+      "Radiation blast"
+    ]
+  },
+  {
+    "name": "Madame Uppercut",
+    "age": 39,
+    "secretIdentity": "Jane Wilson",
+    "powers": [
+      "Million tonne punch",
+      "Damage resistance",
+      "Superhuman reflexes"
+    ]
+  }
+]
+ +

Éste es un JSON perfectamente válido. Para acceder a esta version convertida se debe comenzar con un índice de arreglo, por ejemplo[0]["powers"][0].

+ +

Otras notas

+ + + +

Aprendizaje activo: Trabajando a través de un ejemplo de JSON

+ +

A continuación se muestra un ejemplo de cómo podemos utilizar algunos datos JSON en un sitio web.

+ +

Para comenzar

+ +

Haga una copia local de los archivos heroes.html y style.css. El último contiene un CSS simple para dar estilo a la página, mientras el primero contiene un HTML muy sencillo:

+ +
<header>
+</header>
+
+<section>
+</section>
+ +

Además de un elemento {{HTMLElement("script")}} que contiene el código JavaScript que se escribirá en este ejercicio. En este momento sólo contiene dos líneas, que hacen referencia a los elementos {{HTMLElement("header")}} y {{HTMLElement("section")}} y los almacena en variables:

+ +
const header = document.querySelector('header');
+const section = document.querySelector('section');
+ +

Los datos JSON se encuentran disponibles en GitHub en el siguiente enlace: https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json.

+ +

Los datos se cargarán en esta página y se desplegarán a través de la manipulación del DOM de esta forma:

+ +

+ +

Obteniendo el JSON

+ +

Para obtener el JSON se utilizará un API llamado {{domxref("XMLHttpRequest")}} (a menudo llamado XHR). Éste en un objeto JavaScript muy útil que permite realizar solicitudes de red para recuperar recursos desde un servidor vía JavaScript (por ejemplo: imágenes, texto, JSON, incluso código HTML), con lo que es posible actualizar pequeñas secciones de contenido sin tener que volver a cargar la página entera. Con ello se obtienen páginas web más interactivas, pero está fuera del alcance de este artículo entrar en detalle.

+ +
    +
  1. Para empezar, se debe almacenar la URL del JSON que se quiere recuperar en una variable. Agregue lo siguiente al final del código JavaScript: +
    const requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    +
  2. +
  3. Para crear una solicitud, se necesita crear una nueva instancia de objeto de solicitud desde el constructorXMLHttpRequest, utilizando la palabra clave new. Agregue lo siguiente a continuación de la última línea: +
    const request = new XMLHttpRequest();
    +
  4. +
  5. Ahora es necesario abrir una nueva solicitud utilizando el método open(). Agregue la siguiente línea: +
    request.open('GET', requestURL);
    + +

    Esto requiere al menos dos parámetros — Existen otros parámetros opcionales disponibles. Sólo se requieren los dos obligatorios para este ejemplo:

    + +
      +
    • El método HTTP a usar cuando se hace una solicitud en red. En este caso GET es adecuado, dado que sólo se estan recuperando algunos datos simples.
    • +
    • La URL a la que se realiza la solicitud — esta es la URL del archivo que se almacenó antes.
    • +
    +
  6. +
  7. Luego, agregue las siguientes dos lineas — establecemos el responseType a JSON, de esta forma ese XHR sabe que el servidor estará retornando JSON y que esto debería ser convertido en segundo plano en un objeto JavaScript. Entonces se envía la solicitud con el método send(): +
    request.responseType = 'json';
    +request.send();
    +
  8. +
  9. La última parte de esta sección comprende la espera por la respuesta a retornar desde el servidor y luego, manejarla. Agregue el siguiente código bajo el código previo: +
    request.onload = function() {
    +  const superHeroes = request.response;
    +  populateHeader(superHeroes);
    +  showHeroes(superHeroes);
    +}
    +
  10. +
+ +

En este punto se está almacenando la respuesta a la solicitud (disponible en la propiedad response) en una variable llamada superHeroes; esta variable ahora contendrá el objeto JavaScript basado en el JSON. Luego se pasa el objeto como argumento a dos funciones — la primera llenará el <header> con los datos correctos, mientras la segunda creará una tarjeta de información para cada héroe en el equipo y la insertará en <section>.

+ +

Se ha contenido el código en un manejador de eventos que se activa cuando se dispara el evento de carga (ver onload) — esto es porque el evento de carga se dispara cuando la respuesta ha sido retornada de forma exitosa; de esta manera se garantiza que request.response estará disponible cuando se intente hacer algo con ella.

+ +

Poblando el encabezado

+ +

Se han obtenido los datos desde el JSON y convertidos en un objeto de JavaScript. Ahora, se utilizarán estos datos escribiendo las dos funciones que fueron referenciadas previamente. Antes que todo, agregue la siguiente definición de función a continuación del código previo:

+ +
function populateHeader(jsonObj) {
+  const myH1 = document.createElement('h1');
+  myH1.textContent = jsonObj['squadName'];
+  header.appendChild(myH1);
+
+  const myPara = document.createElement('p');
+  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
+  header.appendChild(myPara);
+}
+ +

Se ha llamado al parámetro jsonObj, para recordar que este es un objeto JavaScript originado desde un JSON. Primero se crea un elemento {{HTMLElement("h1")}} con createElement(), se asigna su textContent igual a la propiedad squadName del objeto, luego se agrega al encabezado utilizandoappendChild(). A continuación se realiza una operación muy parecida en un párrafo: se crea, se asigna su contenido de texto y se agrega al encabezado. La única diferencia es que su texto se asigna a una cadena concatenada que contiene las propiedades homeTown y formed del objeto.

+ +

Creación de las tarjetas de información del héroe

+ +

Luego, agregue la siguiente función al final del código, que crea y muestra las tarjetas de los superhéroes:

+ +
function showHeroes(jsonObj) {
+  const heroes = jsonObj['members'];
+
+  for (var i = 0; i < heroes.length; i++) {
+    const myArticle = document.createElement('article');
+    const myH2 = document.createElement('h2');
+    const myPara1 = document.createElement('p');
+    const myPara2 = document.createElement('p');
+    const myPara3 = document.createElement('p');
+    const myList = document.createElement('ul');
+
+    myH2.textContent = heroes[i].name;
+    myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
+    myPara2.textContent = 'Age: ' + heroes[i].age;
+    myPara3.textContent = 'Superpowers:';
+
+    const superPowers = heroes[i].powers;
+    for (var j = 0; j < superPowers.length; j++) {
+      const listItem = document.createElement('li');
+      listItem.textContent = superPowers[j];
+      myList.appendChild(listItem);
+    }
+
+    myArticle.appendChild(myH2);
+    myArticle.appendChild(myPara1);
+    myArticle.appendChild(myPara2);
+    myArticle.appendChild(myPara3);
+    myArticle.appendChild(myList);
+
+    section.appendChild(myArticle);
+  }
+}
+ +

Para empezar, se almacena la propiedad members del objeto JavaScript en una nueva variable. Este arreglo contiene múltiples objetos que contienen la información para cada héroe.

+ +

A continuación, se utiliza un ciclo for para recorrer cada objeto en el arreglo. Para cada uno:

+ +
    +
  1. Se crean varios elementos nuevos: un<article>, un <h2>, tres <p>s, y una <ul>.
  2. +
  3. Se asigna al <h2> para que muestre el name del héroe.
  4. +
  5. Se completan los tres párrafos con su secretIdentity, age, y una línea que diga "Superpowers:" para introducir la información de la lista.
  6. +
  7. Se almacena la propiedad powers en otra variable nueva llamada superPowers — que contiene un arreglo que lista los superpoderes del héroe actual.
  8. +
  9. Para recorrer los superpoderes del héroe, se utiliza otro ciclo for  — para cada uno se crea un elemento <li>, se asigna el superpoder a él y luego se pone el listItem dentro del elemento <ul>  (myList) utilizando appendChild().
  10. +
  11. Lo último es agregar los <h2>, <p>s, y <ul> dentro del <article> (myArticle), luego se agrega <article> dentro de <section>. El orden en que las cosas son agregadas es importante, dado que este es el orden en el que aparecerán dentro del HTML.
  12. +
+ +
+

Nota: Si tiene problemas en lograr que el ejemplo funcione, intente con el código fuente heroes-finished.html (vea también running live.)

+
+ +
+

Nota: Si encuentra dificultades en seguir la notacion de punto/corchete que se utiliza para acceder a los objetos de JavaScript, puede ser útil tener el archivo superheroes.json abierto en otra pestaña o en su editor de texto, y revisarlo mientras observa el código JavaScript. También puede referirse al artículo JavaScript object basics para mayor información sobre la notación de punto y corchete.

+
+ +

Conversiones entre objetos y texto

+ +

El ejemplo anterior era simple en términos de acceder al objeto JavaScript, porque se programó la solicitud XHR para convertir el JSON de respuesta directamente en un objeto de JavaScript utilizando:

+ +
request.responseType = 'json';
+ +

En algunas ocasiones, se recibirá una cadena JSON sin procesar, y será necesario convertirla en un objeto. Y cuando sea necesario enviar un objeto Javascript a través de la red, será necesario convertirlo a un JSON (una cadena) antes de ser enviado. Afortunadamente, estos dos problemas son muy comunes en el desarrollo web por lo que un objeto JSON integrado está disponible en los navegadores, que contiene los siguientes dos métodos:

+ + + +

El primer método se puede observar en el ejemplo heroes-finished-json-parse.html (vea el código fuente) — que realiza exactamente lo mismo que el ejemplo que se construyó previamente, excepto porque se determinó que el XHR devolviera el texto JSON sin procesar, luego se utiliza parse() para convertirlo en un objeto JavaScript. El extracto del código es el siguiente:

+ +
request.open('GET', requestURL);
+request.responseType = 'text'; // recibimos una cadena de tipo "string"
+request.send();
+
+request.onload = function() {
+  const superHeroesText = request.response; // cogemos la cadena de response
+  const superHeroes = JSON.parse(superHeroesText); // la convertimos a objeto
+  populateHeader(superHeroes);
+  showHeroes(superHeroes);
+}
+ +

Como es de suponer, stringify() trabaja de la forma opuesta. Intente ingresar las siguientes líneas en la consola de JavaScript de su navegador para verlo en acción:

+ +
const myJSON = { "name": "Chris", "age": "38" };
+myJSON
+const myString = JSON.stringify(myJSON);
+myString
+ +

En este caso, se ha creado un objeto JavaScript, luego se comprueba lo que contiene, y entonces se convierte en una cadena JSON utilizando stringify() — guardando el valor retornado en una variable nueva  — y comprobándolo nuevamente.

+ +

Resumen

+ +

En este artículo se ha entregado una guía simple para utilizar JSON en sus programas, incluyendo cómo crear y leer JSON, y cómo acceder a los datos almacenados en él. En el artículo siguiente se verá JavaScript orientado a objetos.

+ +

Vea también

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}

diff --git a/files/es/learn/javascript/objects/object-oriented_js/index.html b/files/es/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..5eb023c685 --- /dev/null +++ b/files/es/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,307 @@ +--- +title: JavaScript orientado a objetos para principiantes +slug: Learn/JavaScript/Objects/Object-oriented_JS +tags: + - Aprender + - Artículo + - Constructor + - Crear + - Create + - JSOO + - JavaScript + - OOJS + - OOP + - Object + - Objeto + - Orientado a Objeto + - Principiante + - Programación orientada a objetos + - instance + - instanciar + - 'l10n:priority' +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}
+ +

Con lo básico fuera del camino, nos enfocaremos en Javascript Orientado a Objetos (JSOO) — este artículo presenta una descripción básica de la teoría de la Programación Orientada a Objetos (POO), luego explora cómo Javascript emula classes de objetos via funciones constructoras, y cómo crea instancias de objetos.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de computación, entendimiento básico de HTML y CSS, familiaridad con las bases de Javascript (ver Primeros pasos con JavaScript y Bloques de construcción JavaScript) y las bases de JSOO (ver Introducción a objetos).
Objetivo: +

Entender la teoría base de la programación orientada a objetos, como se relaciona esta con JavaScript ("todo es un objeto"), y como crear constructores e instacias de objetos.

+
+ +

Programacion Orientada a Objetos— lo básico

+ +

Para empezar, daremos una descripción simple y de alto nivel acerca de lo que es la Programación Orientada a Objetos (POO). Decimos simple, porque la POO puede volverse complicada rápidamente, y darte un tratamiento completo ahora, probablemente podría confundirte más que ayudar. La idea básica de la POO es que usamos objetos para modelar cosas del mundo real que queremos representar en nuestros programas, y/o proveemos una simple manera para acceder a la funcionalidad que, de otra manera, sería difícil o imposible de usar.

+ +

Los objetos pueden contener información y código relacionados, los cuales representan información acerca de lo que estás tratando de modelar, y la funcionalidad o comportamiento que deseas que tenga.  Los datos de un Objeto (y frecuentemente, también las funciones) se pueden almacenar ordenadamente (la palabra oficial es encapsular) dentro del paquete de un objeto (al que se puede asignar un nombre específico, llamado a veces espacio de nombres), haciéndolo fácil de estructurar y acceder; los objetos también se usan comúnmente como almacenes de datos que se pueden enviar fácilmente a través de la red.

+ +

Definiendo una plantilla de objeto

+ +

Vamos a considerar un sencillo programa que muestra información sobre estudiantes y profesores en una escuela. Aquí daremos un vistazo a la POO (Programación Orientada a Objetos) en general, no en el contexto de algún lenguaje de programación específico.

+ +

Para empezar, podríamos volver a ver al objeto Persona de nuestro artículo de primeros objetos, que define los datos generales y funcionalidades de una persona. Hay muchas cosas que podrías saber acerca de una persona (su dirección, estatura, tamaño de calzado, perfil de ADN, número de pasaporte, rasgos significativos de su personalidad...), pero, en este caso, solo estamos interesados en mostrar su nombre, edad, género e intereses, además de una pequeña introducción sobre este individuo basada en los datos anteriores. También queremos que sea capaz de saludar. 

+ +

Esto es conocido como abstracción —  crear un modelo simple de algo complejo que represente sus aspectos más importantes y que sea fácil de manipular para el propósito de nuestro programa.

+ +

+ +

En algunos lenguajes de POO, esta definición de tipo de objeto se la llama class (JavaScript utiliza diferentes mecanismos y terminologías, como verás a continuación) — esto no es en realidad un objeto, en vez de esto es un modelo que define las características que un objeto debería tener.

+ +

Creando objetos

+ +

Partiendo de nuestra clase, podemos crear instancias de objetos — objetos que contienen los datos y funcionalidades definidas en la clase original. Teniendo a nuestra clase Persona, ahora podemos crear gente con características más específicas: 

+ +

+ +

Cuando una instancia del objeto es creada a partir de una clase, se ejecuta la función constructora (constructor en inglés) de la clase para crearla. El proceso de crear una instancia del objeto desde una clase se llama instanciación.

+ +

Clases especializadas

+ +

En este caso nosotros no queremos personas genericas — queremos docentes y estudiantes, que son los dos tipos más específicos de personas. En POO, podemos crear nuevas clases basadas en otras clases, estas nuevas clases secundarias se pueden hacer para  heredar los datos y código de su clase primaria, de modo que pueden reutilizar la funcionalidad común a todos los tipos de objetos en lugar de tener que duplicarla. Cuando la funcionalidad difiere entre clases, puedes definir funciones especializadas directamente en ellas según sea necesario.

+ +

+ +

Esto es realmente útil, los profesores y los estudiantes comparten muchas características comunes como el nombre, el género y la edad, por lo que es conveniente tener que definir esas características solo una vez. También puedes definir la misma característica por separado en diferentes clases, ya que cada definición de esa característica estará en un espacio de nombres diferente. Por ejemplo, el saludo de un estudiante puede tener la forma "Yo, soy [Nombre]" (por ejemplo, Yo, soy Sam), mientras que un profesor puede usar algo más formal, como "Hola, mi nombre es [Prefix] [lastName], y enseño [Asunto] ". (Por ejemplo, Hola, mi nombre es Sr. Griffiths, y yo enseño Química).

+ +
+

Nota:  la palabra elegante para la capacidad de múltiples tipos de objetos de implementar la misma funcionalidad es polimorfismo. Por si acaso te preguntabas.

+
+ +

Ahora puedes crear instancias de objetos de las clases "hijo". Por ejemplo:

+ +

+ +

En el resto del articulo, comenzaremos a ver como podemos practicar la teoría de POO en JavaScript.

+ +

Constructores e instancias de objetos

+ +

Algunas personas sostienen que JavaScript no es un verdadero lenguaje orientado a objetos — por ejemplo, su enunciado class es sólo azúcar sintáctica sobre la herencia prototípica existente y no es una class en el sentido tradicional. JavaScript, utiliza funciones especiales llamadas funciones constructoras para definir objetos y sus características. Son útiles porque a menudo te encontrarás con situaciones en las que no sabes cuántos objetos crearás; los constructores proporcionan los medios para crear tantos objetos como necesites de una manera efectiva, adjuntando datos y funciones a ellos según sea necesario.

+ +

Cuando se crea una nueva instancia del objeto a partir de una función constructora, su funcionalidad central (tal como se define en su prototipo, que exploraremos en el artículo Prototipos de objetos) no se copia en el nuevo objeto como lenguajes OO "clásicos", sino que la funcionalidad está vinculada a través de una cadena de referencia llamada cadena prototipo. Así que esto no es una verdadera instanciación, estrictamente hablando, JavaScript usa un mecanismo diferente para compartir funcionalidad entre objetos.

+ +
+

Nota: no ser "POO clásica" no es necesariamente algo malo; Como se mencionó anteriormente, la POO puede ser muy compleja muy rápidamente, y JavaScript tiene algunas agradables formas de aprovechar las características de la OO sin tener que profundizar demasiado en ello.

+
+ +

Exploremos la creación de clases a través de constructores y la creación de instancias de objetos a partir de ellas en JavaScript. En primer lugar, nos gustaría que hicieras una nueva copia local del archivo oojs.html que vimos en nuestro primer artículo de Objetos.

+ +

Un ejemplo simple

+ +
    +
  1. Comencemos por ver cómo puedes definir una persona con una funcion normal. Agrega esta funcion dentro del elemento script: + +
    function createNewPerson(name) {
    +  var obj = {};
    +  obj.name = name;
    +  obj.greeting = function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  };
    +  return obj;
    +}
    +
  2. +
  3. Ahora puedes crear una nueva persona llamando a esta funcion — prueba con las siguientes lineas en la consola Javascript de tu navegador: +
    var salva = createNewPerson('Salva');
    +salva.name;
    +salva.greeting();
    + Esto funciona bastante bien, pero es un poco largo; si sabemos que queremos crear un objeto, ¿por qué necesitamos crear explícitamente un nuevo objeto vacío y devolverlo? Afortunadamente, JavaScript nos proporciona un práctico acceso directo, en forma de funciones constructoras — ¡hagamos una ahora!
  4. +
  5. Reemplaza tu función anterior por la siguiente: +
    function Person(name) {
    +  this.name = name;
    +  this.greeting = function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  };
    +}
    +
  6. +
+ +

La función constructora es la versión de JavaScript de una clase. Notarás que tiene todas las características que esperas en una función, aunque no devuelve nada o crea explícitamente un objeto — básicamente sólo define propiedades y métodos. Verás que la palabra clave this se está usando aquí también — es básicamente decir que cuando se crea una de estas instancias de objeto, la propiedad name del objeto será igual al valor del nombre pasado a la llamada del constructor, y el método greeting() usará también el valor del nombre pasado a la llamada del constructor.

+ +
+

Nota: Un nombre de función constructora generalmente comienza con una letra mayúscula — esta convención se utiliza para hacer que las funciones constructoras sean más fáciles de reconocer en el código.

+
+ +

Entonces, ¿cómo llamamos a un constructor para crear algunos objetos?

+ +
    +
  1. Agrega las siguientes líneas debajo de tu código anterior: +
    var person1 = new Person('Bob');
    +var person2 = new Person('Sarah');
    +
  2. +
  3. Guarda el código y vuelve a cargarlo en el navegador, e intenta ingresar las siguientes líneas en la consola Javascript : +
    person1.name
    +person1.greeting()
    +person2.name
    +person2.greeting()
    +
  4. +
+ +

¡Guaw! Ahora veras que tenemos dos nuevos objetos, cada uno de los cuales está almacenado en un espacio de nombres diferente: para acceder a sus propiedades y métodos, debes llamarlos como person1 o  person2; están cuidadosamente empaquetados para que no entren en conflicto con otras funciones. Sin embargo, tienen disponible la misma propiedad name y el método greeting(). Ten en cuenta que están utilizando su propio name que se les asignó cuando se crearon; esta es una razón por la cual es muy importante usar this, para que usen sus propios valores, y no algún otro valor.

+ +

Veamos nuevamente las llamadas del constructor:

+ +
var person1 = new Person('Bob');
+var person2 = new Person('Sarah');
+ +

En cada caso, la  palabra clave new se usa para indicarle al navegador que queremos crear una nueva instancia del objeto, seguida del nombre de la función con sus parámetros requeridos entre paréntesis, y el resultado se almacena en una variable — muy similar a cómo se llama a una función estándar. Cada instancia se crea de acuerdo con esta definición:

+ +
function Person(name) {
+  this.name = name;
+  this.greeting = function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  };
+}
+ +

Una vez creados los nuevos objetos, las variables person1 y person2 contienen los siguientes objetos:

+ +
{
+  name: 'Bob',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+
+{
+  name: 'Sarah',
+  greeting: function() {
+    alert('Hi! I\'m ' + this.name + '.');
+  }
+}
+ +

Ten en cuenta que cuando llamamos a nuestra función constructora, estamos definiendo greeting() cada vez, lo cual no es lo ideal. Para evitar esto, podemos definir funciones en el prototipo, que veremos más adelante.

+ +

Creando nuestro constructor final

+ +

El ejercicio que vimos anteriormente fue solo un ejemplo simple para comenzar. Ahora crearemos nuestra función constructor Person() final.

+ +
    +
  1. Elimina el código que insertaste hasta ahora y agrega este constructor de reemplazo; este es exactamente el mismo que el ejemplo simple del principio, con un poco más de complejidad: +
    function Person(first, last, age, gender, interests) {
    +  this.name = {
    +    'first': first,
    +    'last' : last
    +  };
    +  this.age = age;
    +  this.gender = gender;
    +  this.interests = interests;
    +  this.bio = function() {
    +    alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
    +  };
    +  this.greeting = function() {
    +    alert('Hi! I\'m ' + this.name.first + '.');
    +  };
    +}
    +
  2. +
  3. Ahora, agrega la siguiente línea para crear una instancia del objeto: +
    var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
    +
  4. +
+ +

Ahora verás que puedes acceder a las propiedades y métodos justo como lo hiciste anteriormente — intenta esto en tu consola JS:

+ +
person1['age']
+person1.interests[1]
+person1.bio()
+// etc.
+ +
+

Nota: Si tienes problemas para lograr que funcione, puedes comparar tu código con nuestra versión — ve oojs-class-finished.html (también lo puedes ver corriendo en vivo).

+
+ +

Ejercicios adicionales

+ +

Para empezar, intenta añadir un par de líneas de creación de objetos propias, y trata de obtener y asignar valores a los miembros de las instancias del objeto.

+ +

Además, hay un par de problemas con nuestro método bio() — la salida siempre incluye el pronombre "He", incluso para personas de otros géneros. Y bio solamente incluye dos intereses, sin importar la cantidad que hay en el arreglo interests. ¿Podrías corregir esto en la definición de la clase (constructor)? Puedes poner cualquier código dentro de un constructor (probablemente necesites algunos condicionales y un bucle). Piensa como se deben estructurar las declaraciones dependiendo del género, y de la cantidad de intereses.

+ +
+

Note: Si estás atascado, hay una respuesta en nuestro repositorio de GitHub (see it live) — igualmente ¡intentea resolverla primero!

+
+ +

Otras formas de crear instancias de objetos

+ +

Hasta ahora hemos visto dos diferentes formas de crear una instancia de objeto — declarando un objeto literal, y usando una función constructora (ver arriba).

+ +

Esto tiene sentido, pero hay otras formas — se muestran aquí para que te vayas familiarizando en caso de encontrarte con ellas.

+ +

El constructor Object()

+ +

Antes que nada, puedes usar el constructor Object() para crear un nuevo objeto. Si, incluso objetos genéricos tienen un constructor que genera un objeto vacío.

+ +
    +
  1. Intenta ingresar este código en la consola JavaScript de tu navegador: +
    var person1 = new Object();
    +
  2. +
  3. Esto guarda un objeto vacío en la variable person1. Luego pueded agregar propiedades y métodos a este objeto usando la notación de punto (.) o de corchetes (['']); prueba estos ejemplos en tu consola: +
    person1.name = 'Chris';
    +person1['age'] = 38;
    +person1.greeting = function() {
    +  alert('Hi! I\'m ' + this.name + '.');
    +};
    +
  4. +
  5. También puedes pasar un objeto literal como parámetro al constructor Object(), para precargarlo con propiedades/métodos. Prueba esto en tu consola: +
    var person1 = new Object({
    +  name: 'Chris',
    +  age: 38,
    +  greeting: function() {
    +    alert('Hi! I\'m ' + this.name + '.');
    +  }
    +});
    +
  6. +
+ +

Usando el método create()

+ +

Los constructores te pueden ayudar a ordenar tu código — puedes crear constructores en un lugar, y luego crear instancias cuando sean necesarias.

+ +

Sin embargo, algunas personas prefieren crear instancias de objetos sin crear antes constructores, especialmente si van a crear solamente pocas instancias de un objeto.

+ +

JavaScript tiene un método llamado create() que permite hacer esto. Con este método puedes crear un nuevo objeto basado en cualquier otro objeto existente.

+ +
    +
  1. Con tu ejercicio de la sección anterior cargado en el navegador, prueba esto en tu consola JavaScript +
    var person2 = Object.create(person1);
    +
  2. +
  3. Y ahora prueba esto: +
    person2.name
    +person2.greeting()
    +
  4. +
+ +

Verás que person2 fue creado basado en person1 — tiene las mismas propiedades y métodos.

+ +

Una limitación del método create() es que no está soportado por el navegador IE8. Por lo que los constructores serán más efectivos sin necesitas soportar navegadores antiguos.

+ +

Más tarde, exploraremos en detalle los efectos de create().

+ +

Resumen

+ +

Este artículo provee una visión simplificada de la teoría de la orientación a objetos — esta no es toda la historia, pero te da una idea de con que estamos lidiando aquí. Adicionalmente, empezamos a ver como JavaScript está relacionado y difiere de la orientación a objetos "clásica", cómo usamos funciones constructoras para implementar clases en JavaScript, y diferentes formas de generar instancias de objetos.

+ +

En el próximo artículo, exploraremos los prototipos de objeto JavaScript.

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}

+ +

En este modulo

+ + diff --git a/files/es/learn/javascript/objects/object_prototypes/index.html b/files/es/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..852dd5e70e --- /dev/null +++ b/files/es/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,282 @@ +--- +title: Prototipos de objetos +slug: Learn/JavaScript/Objects/Object_prototypes +tags: + - Aprender + - Artículo + - Cadena de Prototipos + - Constructor + - JavaScript + - Objetos + - Principiante + - Prototipo + - create() +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}
+ +

Los prototipos son un mecanismo mediante el cual los objetos en JavaScript heredan características entre sí. En este artículo, explicaremos como funcionan los prototipos y también cómo se pueden usar las propiedades de estos para añadir métodos a los contructores existentes.

+ + + + + + + + + + + + +
Prerrequisitios:Conocer las funciones en Javascript, conocimientos básicos de Javascript (ver Primeros Pasos y Building blocks) y Javascript orientado a Objetos (ver Introducción a Objetos).
Objetivo:Comprender los prototipos de objectos de Javascript, cómo funciona la cadena de prototype, y cómo añadir nuevos métodos a la propiedad prototype.
+ +

¿Un lenguaje basado en prototipos?

+ +

JavaScript es a menudo descrito como un lenguaje basado en prototipos - para proporcionar mecanismos de herencia, los objetos pueden tener un objeto prototipo, el cual actúa como un objeto plantilla que hereda métodos y propiedades.

+ +

Un objeto prototipo del objeto puede tener a su vez otro objeto prototipo, el cual hereda métodos y propiedades, y así sucesivamente. Esto es conocido con frecuencia como la cadena de prototipos, y explica por qué objetos diferentes pueden tener disponibles propiedades y métodos definidos en otros objetos.

+ +

Bien, para ser exactos, los métodos y propiedades son definidos en la propiedad prototype, que reside en la función constructora del objeto, no en la instancia misma del objeto.

+ +

En JavaScript, se establece un enlace entre la instancia del objeto y su prototipo (su propiedad __proto__, la cual es derivada de la propiedad prototype sobre el constructor), y las propiedades y metodos son encontrados recorriendo la cadena de prototipos.

+ +

Nota: Es importante entender que, tanto el prototipo de la instancia de un objeto (al cual se accede mediante Object.getPrototypeOf(obj), o a través de la propiedad __proto__) como el prototipo que contiene el constructor (que se encuentra en la propiedad prototype del constructor) hacen referencia al mismo objeto.

+ +

Vamos a echar un vistazo a algunos ejemplos para intentar aclarar estos conceptos.

+ +

Entendiendo objectos prototipos

+ +

Volvamos al ejemplo anterior en el que acabamos definiendo nuestro constructor Person() — cargue el ejemplo en su navegador. Si aún no lo tienes luego de haber trabajado el último artículo, usa nuestro ejemplo oojs-class-further-exercises.html (vea también el código fuente).

+ +

En este ejemplo, hemos definido una función constructor, así:

+ +
function Persona(nombre, apellido, edad, genero, intereses) {
+
+  // definiendo de propiedades y métodos
+  this.first = first;
+  this.last = last;
+//...
+}
+
+ +

Entonces hemos creado una instancia de un objeto como este:

+ +
var person1 = new Persona('Bob', 'Smith', 32, 'hombre', ['music', 'skiing']);
+ +

Si escribe "person1." en su consola JavaScript, debería ver que el navegador intenta completarlo automáticamente con los nombres de miembro disponibles en este objeto:

+ +

+ +

En esta lista, podra ver los miembros definidos en el objeto prototipo de person1, que es la Persona() (Persona() es el constructor) - nombre, edad, género, intereses, biografía y saludos. Sin embargo, también verá algunos otros miembros - watch, valueOf, etc - que están definidos en el objeto prototipo de Persona() 's, que es un Objeto (Object). Esto demuestra que el prototipo cadena funciona.

+ +

+ +

Entonces, ¿qué sucede si llama a un método en person1, que está definido en Object? Por ejemplo:

+ +
person1.valueOf()
+ +

Este método valueOf() simplemente retornará el valor del objeto sobre el que se llama - ¡pruébalo y verás! En este caso, lo que pasa es que:

+ + + +
+

Nota: Queremos reiterar que los métodos y propiedades no se copian de un objeto a otro en la cadena del prototipo. Ellos son accedidos subiendo por la cadena como se ha descrito anteriormente.

+
+ +
+

Nota: No existe oficialmente una forma de acceder directamente al objeto prototipo de un objeto - los "enlaces" entre los elementos de la cadena están definidos en una propiedad interna, denominada [[prototipo]] en la especificación del lenguaje JavaScript (ver {{glossary("ECMAScript")}}).

+ +

La mayoría de los navegadores modernos, sin embargo, ofrecen una propiedad disponible llamada __proto__ (es decir, 2 subrayados en cada lado), que contiene el objeto prototipo del constructor del objeto. Por ejemplo, pruebe person1.__proto__ y person1.__proto__.__proto__ para ver cómo se ve la cadena en código!

+ +

Desde ECMAScript 2015 se puede acceder indirectamente al objeto prototipo de un objeto mediante Object.getPrototypeOf(obj).

+
+ +

La propiedad prototype: Donde se definen los miembros hereditarios

+ +

Entonces, ¿dónde se definen las propiedades y métodos heredados? Si miras la página de referencia de Object, verás en la parte izquierda un gran número de propiedades y métodos - muchos más que el número de miembros heredados que vimos disponibles en el objeto person1. Algunos son heredados y otros no, ¿por qué?

+ +

La respuesta es que los heredados son los que están definidos en la propiedad prototype (podría llamarse subespacio de nombres), es decir, los que empiezan con Object.prototype, y no los que empiezan sólo con Object. El valor de la propiedad del prototipo es un objeto, que es básicamente un repositorio(bucket) para almacenar propiedades y métodos que queremos que sean heredados por los objetos más abajo en la cadena del prototipo.

+ +

Así que Object.prototype.watch(), Object.prototype.valueOf(), etc., están disponibles para cualquier tipo de objeto que herede de Object.prototype, incluyendo nuevas instancias de objeto creadas desde el constructor.

+ +

Object.is(), Object.keys(), y otros miembros no definidos dentro del prototipo del repositorio(bucket) no son heredados por instancias de objeto o tipos de objeto que heredan de Object.prototype. Sino que son métodos/propiedades disponibles sólo en el propio constructor Object().

+ +
+

Nota: Esto parece extraño - ¿cómo se puede tener un método definido en un constructor, que en sí mismo es una función? Bueno, una función es también un tipo de objeto - vea la referencia del constructor de Function() si no nos cree.

+
+ +
    +
  1. Puede comprobar las propiedades de los prototipos existentes - vuelva a nuestro ejemplo anterior e intente introducir lo siguiente en la consola JavaScript: +
    Person.prototype
    +
  2. +
  3. El resultado no le mostrará mucho - después de todo, no hemos definido nada en el prototipo de nuestro constructor personalizado! Por defecto, el prototipo de un constructor siempre comienza vacío. Ahora intente lo siguiente: +
    Object.prototype
    +
  4. +
+ +

Verá un gran número de métodos definidos en la propiedad Prototype de Object, que están disponibles en los objetos que heredan de Object, como se ha mostrado anteriormente.

+ +

Verá otros ejemplos de herencia de cadena de prototipos en todo JavaScript - intente buscar los métodos y propiedades definidas en el prototipo de los objetos globales String, Date, Number y Array, por ejemplo. Todos ellos tienen un número de miembros definidos en su prototipo, por lo que, por ejemplo, cuando se crea una cadena, como ésta:

+ +
var myString = 'Esto es mi String.';
+ +

myString inmediatamente tiene una serie de métodos útiles disponibles en él, como split(), indexOf(), replace(), etc.

+ +
+

Importante: La propiedad prototype es una de las partes más confusamente nombradas de JavaScript - podría pensarse que this apunta al objeto prototipo del objeto actual, pero no lo hace (es un objeto interno al que puede accederse mediante __proto__, ¿recuerda?). en su lugar, prototype es una propiedad que contiene un objeto en el que se definen los miembros que se desea que se hereden.

+
+ +

Revisando create()

+ +

Anteriormente mostramos cómo Object.create() crea una nueva instancia de objeto.

+ +
    +
  1. Por ejemplo, pruebe esto en la consola JavaScript de su ejemplo anterior: +
    var person2 = Object.create(person1);
    +
  2. +
  3. Lo que hace create() es crear un nuevo objeto a partir de un objeto prototipo específico. Aquí, la person2 se crea utilizando la person1 como objeto prototipo. Puede comprobarlo introduciendo lo siguiente en la consola: +
    person2.__proto__
    +
  4. +
+ +

Esto devolverá el objeto Persona.

+ +

La propiedad constructor

+ +

Cada función de constructor tiene una propiedad prototype cuyo valor es un objeto que contiene una propiedad constructor. Esta propiedad constructor apunta a la función constructor original.

+ +

Como verá en la siguiente sección, las propiedades definidas en la propiedad Person.prototype (o en general en la propiedad prototype de una función de constructor, que es un objeto, como se mencionó en la sección anterior) se hacen disponibles a todas las instancias de objetos creadas utilizando el constructor Person(). Por lo tanto, la propiedad del constructor también está disponible tanto para los objetos person1 como para los objetos person2.

+ +
    +
  1. Por ejemplo, pruebe estos comandos en la consola: +
    person1.constructor
    +person2.constructor
    + +

    Ambos deberían devolver el constructor Person(), ya que contienen la definición original de esas instancias.

    + +

    Un truco interesante es que se puede añadir paréntesis al final de la propiedad constructor (añadiendo todos los parámetros requeridos) para crear otra instancia desde ese constructor. Después de todo, el constructor es una función, por lo que puede ser invocada usando paréntesis; solamente se necesita incluir la palabra clave new para especificar que se quiere usar la función como un constructor.

    +
  2. +
  3. Inténtese esto en la consola: +
    let person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);
    +
  4. +
  5. Ahora intente acceder a las características del nuevo objeto, como: +
    person3.name.first
    +person3.age
    +person3.bio()
    +
  6. +
+ +

Esto funciona. No se necesita usarlo con frecuencia, pero puede ser realmente útil cuando se quiera crear una instancia nueva y por alguna razón no se tenga disponible fácilmente una referencia al constructor original.

+ +

La propiedad constructor tiene otros usos. Por ejemplo, si se tiene una instancia y se quiere devolver el nombre del que el constructor es una instancia, se puede usar lo siguiente:

+ +
instanceName.constructor.name
+ +

Intente esto, por ejemplo:

+ +
person1.constructor.name
+
+ +
+

Nota: El valor de constructor.name puede cambiar (debido a herencia de prototipos, binding, preprocesores, transpiladores, etc.), por lo que para ejemplos más complejos es preferible usar el operador instanceof en su lugar. 

+
+ +
    +
+ +

Modificando prototipos

+ +

Vamos a echar un vistzo a un ejemplo para modificar la propiedad prototype de una función constructor (los métodos añadidos a la propiedad prototipo están disponibles en todas las instancias de los objetos creados a partir del constructor).

+ +
    +
  1. Regresemos a nuestro ejemplo oojs-class-further-exercises.html y creemos una copia local del código fuente. Debajo del código JavaScript existente, agrega el siguiente código, el cuál añade un nuevo método a la propiedad prototype del constructor: + +
    Person.prototype.farewell = function() {
    +  alert(this.name.first + ' has left the building. Bye for now!');
    +};
    +
  2. +
  3. Guarda el código y abre la página en el navegador, e ingresa lo siguiente en la entrada de texto. +
    person1.farewell();
    +
  4. +
+ +

Deberías obtener un mensaje de alerta mostrando el nombre de la persona como se define dentro del constructor. Esto es realmente útil, pero lo que es más útil es que toda la cadena de herencia se ha actualizado dinámicamente; automáticamente hace que este nuevo método esté disponible en todas las instancias del objeto creadas desde el constructor

+ +

Piensa sobre esto por un momento. En nuestro código definimos el constructor, luego creamos una insancia del objeto desde el constructor, después agregamos un nuevo método a el prototipo del constructor.

+ +
function Person(first, last, age, gender, interests) {
+
+  // property and method definitions
+
+}
+
+var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
+
+Person.prototype.farewell = function() {
+  alert(this.name.first + ' has left the building. Bye for now!');
+};.
+ +

Pero el método farewell() aún se encuentra disponible en la instancia person1, su funcionalidad disponible ha sido automáticamente actualizada incluído en método recién definido farewell().

+ +
+

Nota: Si estás teniendo problemas haciendo funcionar este ejemplo, echa un vistazo en nuestro ejemplo oojs-class-prototype.html (míralo ejecutarse en tiempo real).

+
+ +

Raramente verás propiedades definidas en la propiedad prototype, ya no son muy flexibles cuando son definidas de esta forma. Por ejemplo, puedes añadir una propiedad como esta:

+ +
Person.prototype.fullName = 'Bob Smith';
+
+ +

Esto no es muy flexible, ya que la persona podría no llamarse así. Sería mucho mejor construir fullname desde name.first y name.last.

+ +
Person.prototype.fullName = this.name.first + ' ' + this.name.last;
+
+ +

Sin embargo esto no funciona, ya que this estará referenciando al scope global en este caso, no al scope de la función. Llamar esta propiedad retornaría undefined undefined. Esto funcionó bien en el método que declaramos anteriormente dentro del prototipo, porque se encuentra dentro del scope de la función, que se transferirá con éxito al scope de la instancia del objeto.Así que deberías definir propiedades constantes en el prototipo (p.e. una que nunca necesite cambiar), pero generalmente funciona mejor definir propiedades dentro del constructor.

+ +

De hecho, un patrón bastante común para la mayoría de definiciones de objetos es declarar las propiedades dentro del constructor, y los métodos en el prototipo. Esto hace el código más fácil de leer, ya que el constructor sólo contiene las definiciones de propiedades, y los métodos están en bloques separados. Por ejemplo:

+ +
// Constructor with property definitions
+
+function Test(a, b, c, d) {
+  // property definitions
+}
+
+// First method definition
+
+Test.prototype.x = function() { ... };
+
+// Second method definition
+
+Test.prototype.y = function() { ... };
+
+// etc.
+
+ +

Este patrón puede verse en acción en el ejemplo de la aplicación de planificador escolar de Piotr Zalewa.

+ +

Resumen

+ +

Este articulo ha cubierto prototipos de objeto JavaScript, incluyendo como las cadenas de objeto prototipo permiten a los objetos heredar caracteristicas de una a otra, la propiedad prototipo y como puede ser usado para agregar metodos a los constructores, y otros temas relacionados.

+ +

En el proximos articulo vamos a ver como puedes implementar la herencia de funcionalidades entre dos de tus propios objetos personalizados.

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}

+ +

In this module

+ + diff --git a/files/es/learn/performance/index.html b/files/es/learn/performance/index.html new file mode 100644 index 0000000000..ebe81969aa --- /dev/null +++ b/files/es/learn/performance/index.html @@ -0,0 +1,113 @@ +--- +title: Rendimiento web +slug: Learn/Performance +translation_of: Learn/Performance +--- +

{{LearnSidebar}}{{draft}}

+ +

La construcción de sitios web requiere HTML, CSS y JavaScript. Para crear sitios web y aplicaciones que la gente quiera usar, que atraigan y retengan a los usuarios, debe crear una buena experiencia de usuario. Parte de la buena experiencia del usuario es garantizar que el contenido se cargue rápidamente y responda a la interacción del usuario. Esto se conoce como rendimiento web, y en este módulo aprenderá todo lo que necesita para crear sitios web de rendimiento.

+ +

 

+ +

El rendimiento web es la medición objetiva y la experiencia percibida por el usuario del tiempo de carga y el tiempo de ejecución. El rendimiento web es el tiempo que tarda un sitio en cargarse, en ser interactivo y receptivo, y en el grado de fluidez del contenido durante las interacciones del usuario. ¿Es el desplazamiento suave? ¿Se puede hacer clic en los botones? ¿Las ventanas emergentes se abren rápidamente y se animan sin problemas al hacerlo? El rendimiento web incluye mediciones objetivas como el tiempo de carga, cuadros por segundo y tiempo para experiencias interactivas y subjetivas de cuánto tiempo tardó en cargarse el contenido.

+ +

Muchas características afectan el rendimiento, incluida la latencia, el tamaño de la aplicación, la cantidad de nodos DOM, la cantidad de solicitudes de recursos realizadas, el rendimiento de JavaScript, la carga de la CPU y más. Es importante minimizar los tiempos de carga y respuesta, y agregar funciones adicionales para ocultar la latencia al hacer que la experiencia sea lo más accesible e interactiva posible, tan pronto como sea posible, mientras se carga de forma asíncrona en las partes más largas de la experiencia.

+ +

Existen herramientas, API y mejores prácticas que nos ayudan a medir y mejorar el rendimiento web. Los veremos también en el curso de este módulo.

+ +

 

+ +

Camino de aprendizaje

+ +

 

+ +

Si bien es necesario conocer HTML, CSS y JavaScript para implementar muchas recomendaciones de mejora del rendimiento web, saber cómo crear aplicaciones no es una condición previa necesaria para comprender y medir el rendimiento web.

+ +

Varios de los módulos introductorios a continuación no requieren conocimientos de programación, aunque se necesita una comprensión de HTML para el módulo de rendimiento y HTML, se necesita una comprensión de CSS para el módulo de rendimiento y CSS, etc. Recomendamos que trabaje con nuestros módulos introductorios. primero, comenzando con qué es el rendimiento web primero. Los módulos introductorios proporcionan una visión general del rendimiento web. Los tres primeros deben considerarse como lectura obligatoria si usted es un desarrollador o gerente de proyectos. Los módulos enfocados en temas de tecnología son más apropiados para los desarrolladores que utilizan estas tecnologías.

+ +

 

+ +

Los módulos avanzados profundizan en los temas que se resumen en los módulos introductorios y proporcionan una visión general de las API de rendimiento, las herramientas de análisis y prueba y los problemas de cuellos de botella en el rendimiento.

+ +

Se recomienda que trabajes a través de Empezando con la web antes de proceder con este tema. Sin embargo, hacerlo no es absolutamente necesario.

+ +

Modulos de introducción

+ +

Este tema contiene los siguientes módulos, en un orden sugerido para trabajar a través de ellos. Definitivamente debes comenzar con el primero.

+ +
+
¿Qué es el rendimiento web?
+
Este artículo inicia el módulo con una buena visión de lo que realmente es el rendimiento: esto incluye las herramientas, métricas, API, redes y grupos de personas que debemos considerar al pensar en el rendimiento y cómo podemos hacer que el rendimiento sea parte de nuestra web. flujo de trabajo de desarrollo.
+
¿Cómo perciben los usuarios el rendimiento?
+
+

Más importante que la rapidez de su sitio web en milisegundos, es la rapidez con la que los usuarios perciben su sitio. Estas percepciones se ven afectadas por el tiempo real de carga de la página, el ralentí, la capacidad de respuesta a la interacción del usuario y la suavidad del desplazamiento y otras animaciones. En este artículo, analizamos las diversas métricas de carga, animación y métricas de capacidad de respuesta, junto con las mejores prácticas para mejorar la percepción del usuario, si no los tiempos reales.

+
+
Rendimiento web básico
+
Además de los componentes frontales de HTML, CSS, JavaScript y archivos multimedia, hay características que pueden hacer que las aplicaciones sean más lentas y características que pueden hacer que las aplicaciones sean subjetivamente y objetivamente más rápidas. Existen muchas API, herramientas de desarrollo, mejores prácticas y malas prácticas relacionadas con el rendimiento web. Aquí presentaremos muchas de estas funciones al nivel básico y proporcionaremos enlaces a inmersiones más profundas para mejorar el rendimiento de cada tema.
+
Herramientas de rendimiento HTML
+
Algunos atributos y el orden de origen de su marcado pueden afectar el rendimiento o su sitio web. Al minimizar el número de nodos DOM, asegurándose de que se utilicen el mejor orden y los atributos para incluir contenido como estilos, scripts, medios y scripts de terceros, puede mejorar drásticamente la experiencia del usuario. Este artículo analiza en detalle cómo se puede usar HTML para garantizar el máximo rendimiento.
+
Multimedia: imágenes y vídeo
+
El fruto más bajo del rendimiento web es a menudo la optimización de medios. Es posible servir diferentes archivos multimedia según la capacidad, el tamaño y la densidad de píxeles de cada agente de usuario. Sugerencias adicionales como eliminar pistas de audio de videos de fondo pueden mejorar aún más el rendimiento. En este artículo, analizamos el impacto que el video, el audio y el contenido de la imagen tienen en el rendimiento y los métodos para garantizar que el impacto sea lo más mínimo posible.
+
Imágenes responsivas
+
Si bien la optimización de imágenes es vital para las experiencias de usuario ricas en medios de alto rendimiento, es especialmente importante garantizar que las imágenes tengan el tamaño adecuado para los dispositivos que las descargan. En este artículo, analizaremos la función de las características del navegador nativo, como el elemento <picture> y el atributo srcset en la entrega eficiente de imágenes, y cómo puede usarlas con confianza.
+
Formatos de medios alternativos
+
Cuando se trata de imágenes y videos, hay más formatos de los que probablemente conozca. Algunos de estos formatos pueden llevar sus páginas multimedia altamente optimizadas aún más lejos al ofrecer reducciones adicionales en el tamaño del archivo. En esta guía, analizaremos algunos formatos de medios alternativos, cómo usarlos de manera responsable para que los navegadores no compatibles no se queden al margen, y algunos consejos avanzados sobre la transcodificación de sus activos existentes.
+
Características de rendimiento en CSS
+
CSS puede ser un enfoque de optimización menos importante para mejorar el rendimiento, pero hay algunas características de CSS que afectan el rendimiento más que otras. En este artículo analizamos algunas propiedades CSS que afectan el rendimiento y sugerimos formas de manejar los estilos para garantizar que el rendimiento no se vea afectado negativamente.
+
Mejores prácticas de rendimiento en JavaScript
+
JavaScript, cuando se usa correctamente, puede permitir experiencias web interactivas e inmersivas, o puede dañar significativamente el tiempo de descarga, el tiempo de procesamiento, el rendimiento dentro de la aplicación, la duración de la batería y la experiencia del usuario. Este artículo describe algunas de las mejores prácticas de JavaScript que deben tenerse en cuenta para garantizar que incluso el contenido complejo tenga el mayor rendimiento posible.
+
Rendimiento de fuentes web
+
Un aspecto que a menudo se pasa por alto en el panorama del rendimiento son las fuentes web. Las fuentes web son más prominentes que nunca en el diseño web, sin embargo, muchos desarrolladores simplemente las incorporan desde un servicio de terceros y no piensan en ello. En este artículo, cubriremos métodos para obtener sus archivos de fuentes lo más pequeños posible con una configuración y sub configuración de archivos eficientes. A partir de ahí, continuaremos hablando sobre cómo los navegadores envían mensajes de texto y cómo puede usar las funciones de CSS y JavaScript para garantizar que sus fuentes se representen rápidamente y con una interrupción mínima de la experiencia del usuario.
+
+ +
+
Rendimiento móvil
+
Dado que el acceso a la web en dispositivos móviles es tan popular, y que todas las plataformas móviles tienen navegadores web completos, pero es posible que el ancho de banda, la CPU y la vida útil de la batería sean limitados, es importante considerar el rendimiento de su contenido web en estas plataformas. Este artículo analiza las consideraciones de rendimiento específicas para dispositivos móviles.
+
+ +

Módulos avanzados

+ +
+
Poblando la pagina
+
Se realiza una solicitud HTTP y, con suerte, unos segundos más tarde, aparece el sitio. Mostrar el contenido implica ejecutar JavaScript, posiblemente modificar el DOM, calcular estilos, calcular el diseño y, finalmente, representar el contenido, lo que implica pintar y componer, y puede involucrar la aceleración de la GPU en un hilo separado.
+
Entendiendo la latencia
+
+

La latencia es la cantidad de tiempo que tarda entre el navegador que realiza una solicitud de un recurso y el que recibe el primer byte del recurso solicitado. Este artículo explica qué es la latencia, cómo afecta el rendimiento y cómo medir y mejorar la latencia.

+
+
Entendiendo el ancho de banda
+
+

Bandwidth is the amount of data (measured in Mbps or Kbps) that can be sent per second. This article explains the role of bandwidth in media-rich internet applications, how it can be measured, and how you can optimize applications to make the best use of available bandwidth.

+
+
HTTP/2 y tú
+
+

La capa de transporte, es decir, HTTP, es absolutamente esencial para el funcionamiento de la web, y solo recientemente se ha visto una actualización importante en la forma de HTTP / 2. Fuera de la caja, HTTP / 2 proporciona muchas mejoras de rendimiento y ventajas sobre su predecesor, pero también cambia el panorama. En este artículo, aprenderá lo que HTTP / 2 hace por usted, y cómo ajustar su aplicación para que vaya más allá.

+
+
El rol de TLS en el rendimiento
+
+

TLS, o HTTPS, como solemos llamar, es crucial para crear experiencias de usuario seguras. Si bien el hardware ha reducido los impactos negativos que TLS ha tenido en el rendimiento del servidor, aún representa una porción sustancial del tiempo que pasamos esperando que los navegadores se conecten a los servidores. Este artículo explica el proceso de intercambio de TLS y ofrece algunos consejos para reducir este tiempo, como el grapado OCSP, los encabezados de precarga de HSTS y el posible papel de las sugerencias de recursos en el enmascaramiento de la latencia TLS para terceros.

+
+
Perfilando con el perfilador incorporado
+
Aprenda cómo perfilar el rendimiento de la aplicación con el generador de perfiles integrado de Firefox.
+
Gráficos de rendimiento de lectura
+
Las herramientas del desarrollador proporcionan información sobre el rendimiento, la memoria y las solicitudes de red. Saber leer tablas de cascada, árboles de llamadas, Las herramientas del desarrollador proporcionan información sobre el rendimiento, la memoria y las solicitudes de red. Saber leer, tablas de llamas, y localizaciones en su navegador, las herramientas de desarrollo lo ayudarán a comprender los gráficos de cascada y llama en otras herramientas de rendimiento.
+
Rendimiento de animaciones en CSS y JavaScript
+
Las animaciones son críticas para una experiencia de usuario placentera. Este artículo analiza las diferencias de rendimiento entre CSS y animaciones basadas en JavaScript.
+
Analizando paquetes de JavaScript
+
Sin duda, JavaScript es una gran parte del desarrollo web moderno. Si bien siempre debe esforzarse por reducir la cantidad de JavaScript que utiliza en sus aplicaciones, puede ser difícil saber dónde comenzar. En esta guía, le mostraremos cómo analizar los paquetes de scripts de su aplicación, para que sepa qué está utilizando y cómo detectar si hay scripts duplicados entre paquetes en su aplicación.
+
Lazy-loading JavaScript con importaciones dinámicas
+
Cuando los desarrolladores escuchan el término "carga perezosa", inmediatamente piensan en imágenes que se cargan por la mitad inferior de la página cuando se desplaza hacia la ventana gráfica. ¿Pero sabías que también puedes cargar JavaScript de forma perezosa? En esta guía hablaremos sobre la declaración dinámica de importación (), que es una característica de los navegadores modernos que carga un módulo de JavaScript a pedido. Por supuesto, ya que esta función no está disponible en todas partes, también le mostraremos cómo puede configurar sus herramientas para usar esta función de una manera ampliamente compatible.
+
+ +
+
Controlar la entrega de recursos con sugerencias de recursos
+
Los navegadores a menudo saben mejor que nosotros cuando se trata de la priorización y la entrega de recursos, pero están lejos de ser clarividentes. Las características nativas del navegador nos permiten sugerirle al navegador cuándo debe conectarse a otro servidor, o precargar un recurso antes de que el navegador sepa que lo necesita. Cuando se usa juiciosamente, esto puede hacer que la experiencia rápida parezca aún más rápida. En este artículo, cubrimos las características nativas del navegador como rel = preconnect, rel = dns-prefetch, rel = prefetch, y rel = precarga, y cómo usarlas para su ventaja.
+
+ +

Ver también

+ + + +

{{LandingPageListSubpages}}

diff --git a/files/es/learn/server-side/django/admin_site/index.html b/files/es/learn/server-side/django/admin_site/index.html new file mode 100644 index 0000000000..486d277003 --- /dev/null +++ b/files/es/learn/server-side/django/admin_site/index.html @@ -0,0 +1,372 @@ +--- +title: 'Tutorial Django Parte 4: Sitio de Administración de Django' +slug: Learn/Server-side/Django/Admin_site +tags: + - Aplicación web + - Artículo + - Codificación + - Django Admin + - Principiante + - Python + - Tutorial + - django + - django_admin + - programacion +translation_of: Learn/Server-side/Django/Admin_site +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}
+ +

Ahora que hemos creado modelos para el sitio web de la BibliotecaLocal, usaremos el sitio de administración de Django para añadir algunos datos de libros "reales". Primero mostraremos cómo registrar los modelos en el sitio de administración y luego te mostraremos cómo iniciar sesión y crear algunos datos. Al final del artículo mostraremos algunas formas en las que puedes mejorar más adelante la presentación del sitio de Administración.

+ + + + + + + + + + + + +
Pre-requisitos:Primero completa: Tutorial Django Parte 3: Uso de modelos.
Objetivo: +

Entender los beneficios y las limitaciones del sitio de administración de Django, y usarlo para crear algunos registros para nuestros modelos.

+
+ +

Introducción

+ +

La aplicación de administración de Django puede usar tus modelos para construir automáticamente un área dentro del sitio que puedes usar para crear, consultar, actualizar y borrar registros. Esto puede ahorrarte mucho tiempo de desarrollo, haciendo muy fácil probar tus modelos y darte una idea de si tus datos son correctos. La aplicación de administración también puede ser útil para manejar datos en producción, dependiendo del estilo del sitio web. Desde el proyecto Django solo se recomienda para gestión de datos internos (por ejemplo, solo para uso de administradores o personas internas de tu organización), ya que como enfoque centrado en el modelo no es necesariamente la mejor interfaz posible para todos los usuarios, exponiendo una gran cantidad de detalles innecesarios de los modelos.

+ +

Toda la configuración requerida para incluir la aplicación admin en tu sitio Web fue hecha automaticamente cuando  creaste el esqueleto del proyecto (para información sobre dependencias reales necesarias, vea los documentos de Django aquí). Como resultado, todo lo que  debes hacer para agregar tus modelos a la aplicación admin  es  registrarlos. Al final de este artículo entregaremos una breve demostración sobre como puedes configurar aún más el área de administración para mejorar la visualización de nuestros modelos de datos.

+ +

Después de registrar los modelos te mostraremos como crear un nuevo "administrador", iniciar sesión en el sitio, y crear algunos libros, autores, instancias de libros, y géneros. Esto será útil para probar las vistas y plantillas que empezaremos a crear en el siguiente tutorial.

+ +

Registrando los modelos 

+ +

Primero,  abre admin.py en la aplicación catálogo (/locallibrary/catalog/admin.py). Actualmente se ve como esto — notar que ya importa django.contrib.admin:

+ +
from django.contrib import admin
+
+# Register your models here.
+
+ +

Registra los modelos copiando el texto siguiente al final del archivo. Este simple código esta importando los modelos y después llama a  admin.site.register para registrar a cada uno de ellos.

+ +
from .models import Author, Genre, Book, BookInstance
+
+admin.site.register(Book)
+admin.site.register(Author)
+admin.site.register(Genre)
+admin.site.register(BookInstance)
+
+ +
Nota: Si tu aceptaste el desafío de crear un modelo que represente el Lenguaje natural de un libro (ver el artículo tutorial de modelos), importalo y registralo también!
+ +

Esta es la forma más simple de registrar un modelo, o modelos, con el sitio. El sitio de administración es altamente personalizable,  y hablaremos más sobre otras formas de registrar tus modelos más abajo.

+ +

Creando un administrador

+ +

Para iniciar sesión en el sitio de administración, necesitamos una cuenta de usuario con estado de Personal habilitado. Para ver y crear registros tambien necesitamos que este usuario tenga permisos para administrar todos nuestros objetos. Puedes crear una cuenta  "administrador" que tenga acceso total al sitio y a todos los permisios necesarios usando manage.py.

+ +

Usa el siguiente comando, en el mismo directorio de manage.py, para crear al administrador. Deberás ingresar un nombre de usuario, dirección email, y una  contraseña fuerte.

+ +
python3 manage.py createsuperuser
+
+ +

Una vez el comando termine un nuevo administrador será agregado a la base de datos. Ahora reinicia el servidor de desarrollo para que podamos probrar el inicio de sesión:

+ +
python3 manage.py runserver
+
+
+ +

Iniciar sesión y usar el sitio

+ +

Para iniciar sesión en el sitio, ve a la URL /admin (e.j. http://127.0.0.1:8000/admin) e ingresa tus credenciales de id usuario y contraseña de administrador (serás redirigido a la página login, y entonces volverás a la URL de /admin después de haber ingresado tus datos).

+ +

Esta parte del sitio muestra todos tus modelos, agrupados por aplicación instalada. Puedes hacer click en un nombre de modelo para ir a una pantalla que lista todos los registros asociados, y además puedes hacer click sobre esos registros para editarlos. También puedes hacer click directamente sobre el vínculo Añadir a continuación de cada modelo para comenzar a crear un registro de ese tipo.

+ +

Admin Site - Home page

+ +

Haz click  sobre el vínculo Añadir a la derecha de Books para crear un nuevo libro, esto mostrará un diálogo parecido al de abajo). Nota como los títulos de cada campo, el tipo de widget usado, y el help_text (si existe) corresponde con el valor que especificaste en el modelo. 

+ +

Ingresa valores para los campos. Puede crear nuevos autores o géneros presionandoel botón + a continuación del campo respectivo ( o seleccionar un valor existente de las listas si ya las tenías creadas). Cuando termines puedes presionar  Grabar, Grabar y añadir otro, o Grabar y continuar editando para guardar el registro.

+ +

Admin Site - Book Add

+ +
+

Nota: En este punto nos gustaría que pasaras algún tiempo añadiendo unos pocos libros, autores, y géneros (ej. Fantasía) a tu aplicación. Asegúrate de que cada autor y género incluye un par de libros diferentes (esto hará tus vistas de lista y detalle más interesantes cuando las implementemos más tarde en la serie de artículos).

+
+ +

Cuando hayas terminado de añadir libros, haz click en el enlace Home en el separador de arriba para regresar a la página principal de administración. Luego haz click en el enlace Books para desplegar la lista actual de libros (o en alguno de los otros enlaces para ver las listas de otros modelos). Ahora que haz añadido unos cuantos libros, la lista debería lucir similar a la captura de pantalla de abajo. Se muestra el título de cada libro; que es el valor devuelto por el método __str__() del modelo Book que especificamos en el artículo anterior.

+ +

Admin Site - List of book objects

+ +

Desde esta lista puedes eliminar libros marcando la casilla de verificación junto al libro que no deseas y seleccionando la acción delete... en la lista de selección Action, y luego presionando el botón Go. Puedes también añadir nuevos libros presionando el botón ADD BOOK.

+ +

Puedes editar un libro haciendo click en su nombre en la lista. La página de edición para un libro, como se muestra abajo, es casi idéntica a la página "Add". Las principales diferencias son el título de la página (Change book) y la adición de los botones Delete, HISTORY y VIEW ON SITE (este último aparece porque definimos el método get_absolute_url() en nuestro modelo).

+ +

Admin Site - Book Edit

+ +

Ahora regresa a la página Home (usando el enlace Home de la barra superior) y observa las listas Author y Genre -- ya deberías tener algunos registros creados de cuando añadiste los nuevos libros, pero puedes crear algunos más.

+ +

Lo que no vas a tener es BookInstances, porque estas no se crean de los libros (si bien puedes crear un Book desde una BookInstance -- esta es la naturaleza de los campos ForeignKey). Regresa a la página Home y presiona el botón Add relacionado para desplegar la pantalla Add book instance, como se muestra abajo. Nota el largo y globalmente único Id, que puede ser usado para identificar inequívocamente una única copia de un libro dentro de la biblioteca.

+ +

Admin Site - BookInstance Add

+ +

Crea algunos de estos registros para cada uno de tus libros. Establece el status en Available para al menos algunos registros y en On loan para otros. Si el status es diferente de Available, especifica también una fecha de Due back (devolución).

+ +

¡Eso es todo! Has aprendido a configurar y usar el sitio de administración. También has creado registros para Book, BookInstance, Genre y Author que podremos usar una vez que creemos nuestras propias views (vistas) y templates (plantillas).

+ +

Configuración avanzada

+ +

Django hace un gran trabajo al crear un sitio de administración básico usando la información de los modelos registrados:

+ + + +

Posteriormente puedes personalizar la interfaz para hacerla incluso más fácil de usar. Algunas de las cosas que puedes hacer son:

+ + + +

En esta sección observaremos unos cuantos cambios que mejorarán la interfaz de nuestra LocalLibrary, incluyendo la adición de más información a las listas de los modelos Book y Author, y mejorando el diseño de sus vistas de edición. No cambiaremos la presentación de los modelos Language y Genre debido a que solo tienen un campo cada uno, ¡por lo que no hay ningún beneficio real de hacerlo!

+ +

Puedes encontrar una referencia completa de todas las opciones de personalización del sitio de administración en The Django Admin site (Django Docs).

+ +

Registrar una clase ModelAdmin

+ +

Para cambiar la forma en la que un modelo se despliega en la interfaz de administración debes definir una clase ModelAdmin (que describe el diseño) y registrarla con el modelo.

+ +

Comencemos con el modelo Author. Abre admin.py en la aplicación catalog (/locallibrary/catalog/admin.py). Comenta tu registro original para el modelo Author (colocando el prefijo # en la línea):

+ +
# admin.site.register(Author)
+ +

Ahora añade una nueva clase AuthorAdmin y regístrala como se muestra abajo.

+ +
# Define the admin class
+class AuthorAdmin(admin.ModelAdmin):
+    pass
+
+# Register the admin class with the associated model
+admin.site.register(Author, AuthorAdmin)
+
+ +

Ahora añadiremos clases ModelAdmin para Book, y BookInstance. De nuevo, debemos comentar nuestros registros originales:

+ +
#admin.site.register(Book)
+#admin.site.register(BookInstance)
+ +

Ahora, para crear y registar los nuevos modelos usaremos, para propósitos de esta demostración, la expresión @register para registrar los modelos (hace exactamente lo mismo que admin.site.register()):

+ +
# Register the Admin classes for Book using the decorator
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    pass
+
+# Register the Admin classes for BookInstance using the decorator
+
+@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    pass
+
+ +

Al momento todas nuestras clases de administración estás vacías (observa "pass"), así que el comportamiento de administración ¡no cambiará! Ahora podemos extenderlas para definir nuestro comportamiento de administración específico para cada modelo.

+ +

Configurar las vistas de lista

+ +

La LocalLibrary actualmente lista todos los autores usando el nombre generado por el método __str__() del modelo. Esto funciona bien cuando solo tienes unos pocos autores, pero una vez que tienes muchos puedes terminar teniendo duplicados. Para diferenciarlos, o simplemente para mostrar información más interesante sobre cada autor, puedes usar list_display para añadir otros campos a la vista.

+ +

Reemplaza tu clase AuthorAdmin con el código de abajo. Los nombres de campos a ser desplegados en la lista están declarados en una tupla en el orden requerido, como se muestra (estos son los mismos nombres especificados en tu modelo original).

+ +
class AuthorAdmin(admin.ModelAdmin):
+    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+
+ +

Recarga el sitio y navega hacia la lista de autores. Ahora deberían desplegarse los campos de arriba, así:

+ +

Admin Site - Improved Author List

+ +

Para nuestro modelo Book desplegaremos adicionalmente el author y genre. El author es un campo de relación tipo ForeignKey (uno a uno), y por tanto estará representado por el valor __str__() del registro asociado. Reemplaza la clase BookAdmin con la versión de abajo.

+ +
class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+ +

Desafortunadamente, no podemos especificar directamente el campo genre en list_display porque es un campo ManyToManyField (Django previene esto porque habría un alto "costo" de acceso a base de datos si lo hiciera). En lugar de eso, definiremos una función display_genre para obtener la información como una cadena (esta es la función que hemos llamado arriba; la definiremos más abajo).

+ +
+

Nota: Obtener el genre podría no ser una buena idea aquí, debido al "costo" de la operación en la base de datos. Te mostramos cómo hacerlo porque llamar funciones desde tus modelos puede ser muy útil por otras razones -- por ejemplo para añadir un enlace Delete junto a cada ítem en la lista.

+
+ +

Añade el siguiente código en tu modelo Book (models.py). Esto crea una cadena con los tres primeros valores del campo genre (si existen) y crea una short_description (descripción corta) que puede ser usada en el sitio de administración por este método.

+ +
    def display_genre(self):
+        """
+        Creates a string for the Genre. This is required to display genre in Admin.
+        """
+        return ', '.join([ genre.name for genre in self.genre.all()[:3] ])
+    display_genre.short_description = 'Genre'
+
+ +

Después de guardar el modelo y actualizar admin, recarga el sitio y ve a la página de lista de Books (libros), deberías ver una lista de libros como la de abajo:

+ +

Admin Site - Improved Book List

+ +

El modelo Genre (y el modelo Language, si lo definiste) tiene un solo campo, por lo que no tiene sentido crear un modelo adicional para el mismo para desplegar campos adicionales.

+ +
+

Nota: Vale la pena actualizar el modelo BookInstance para mostrar al menos el estado y fecha de devolución esperada. ¡Lo hemos añadido como un reto al final de este artículo!

+
+ +

Añadir filtros de lista

+ +

Una vez que tienes muchos ítems en una lista, puede ser útil filtrar los ítems que se despliegan. Esto se hace listando campos en el atributo list_filter. Reemplaza tu clase BookInstanceAdmin actual con el fragmento de código de abajo.

+ +
class BookInstanceAdmin(admin.ModelAdmin):
+    list_filter = ('status', 'due_back')
+
+ +

La vista de lista incluirá ahora un cuadro de filtrado a la derecha. Nota como puedes elegir fechas y estados para filtrar los valores:

+ +

Admin Site - BookInstance List Filters

+ +

Organizar el diseño de vista detallada

+ +

Por defecto, las vistas detalladas organizan todos los campos verticalmente, en su órden de declaración en el modelo. Puedes cambiar el orden de declaración, qué campos se despliegan (o excluyen), si se usa secciones para organizar la información, si los campos se despliegan en horizontal o vertical, e incluso qué controles de edición se usan en los formularios de administración.

+ +
+

Nota: Los modelos de la LocalLibrary son relativamente simples, por lo que no tenemos una gran necesidad de cambiar el diseño; sin embargo haremos algunos cambios solo para mostrarte cómo.

+
+ +

Controlando qué campos son desplegados y ordenados

+ +

Actualiza tu clase AuthorAdmin para añadir la línea fields, como se muestra abajo (en negrita):

+ +
class AuthorAdmin(admin.ModelAdmin):
+    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+    fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]
+
+ +

El atributo fields lista solo los campos que se van a desplegar en el formulario, en orden. Los campos se despliegan en vertical por defecto, pero se desplegarán en horizontal si los agrupas en una tupla (como se muestra en los campos "date" arriba).

+ +

Reinicia tu aplicación y ve a la vista de detalle de autor -- ahora debería aparecer como se muestra abajo:

+ +

Admin Site - Improved Author Detail

+ +
+

Nota: Puedes también usar el atributo exclude para declarar una lista de atributos que se excluirán del formulario (todos los demás atributos en el modelo se desplegarán).

+
+ +

Seccionando la vista de detalle

+ +

Puedes añadir "secciones" para agrupar información relacionada del modelo dentro del formulario de detalle, usando el atributo fieldsets.

+ +

En el modelo BookInstance tenemos información relacionada a cuál es el libro (ej. name, imprint e id) y a cuándo estará disponible (status, due_back). Podemos configurarlas en diferentes secciones añadiendo el texto en negrita a nuestra clase BookInstanceAdmin.

+ +
@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    list_filter = ('status', 'due_back')
+
+    fieldsets = (
+        (None, {
+            'fields': ('book', 'imprint', 'id')
+        }),
+        ('Availability', {
+            'fields': ('status', 'due_back')
+        }),
+    )
+ +

Cada sección tiene su propio título (o None, si no quieres un título) y una tupla de campos asociada en un diccionario -- el formato es complicado de describir pero bastante fácil de entender si observas el fragmento de código que se encuentra justo arriba.

+ +

Reinicia y navega a una vista de instancia de libro (book instance); el formulario debería aparecer como se muestra abajo:

+ +

Admin Site - Improved BookInstance Detail with sections

+ +

Edición en cadena de registros asociados

+ +

A veces puede tener sentido el añadir registros asociados al mismo tiempo. Por ejemplo, puede tener sentido el tener información tanto de un libro como de las copias específicas que has adquirido del mismo, en la misma página de detalle.

+ +

Puedes hacerlo declarando inlines, de tipo TabularInline (diseño horizontal) o StackedInline (diseño vertical, tal como el diseño de modelo por defecto). Puedes añadir la información de BookInstance dentro de nuestro detalle de Book añadiendo las líneas de abajo en negrita cerca de tu BookAdmin:

+ +
class BooksInstanceInline(admin.TabularInline):
+    model = BookInstance
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+    inlines = [BooksInstanceInline]
+
+ +

Prueba recargando tu aplicación y observando la vista para un libro -- ahora deberías ver al final las instancias relacionadas a este libro (inmediatamente debajo de los campos de género del libro):

+ +

Admin Site - Book with Inlines

+ +

En este caso, todo lo que hemos hecho es declarar nuestra clase encadenada tabular, que simplemente añade todos los campos del modelo encadenado. Puedes especificar toda clase de información adicional para el diseño incluyendo los campos a mostrar, su órden, si son solo de lectura o no, etc. (ve TabularInline para más información).

+ +
+

Nota: ¡hay algunas lamentables limitaciones a esta funcionalidad! En la captura de pantalla de arriba tenemos tres instancias del libro existentes, seguidas de tres lugares para nuevas instancias del libro (¡que se ven muy similares!). Sería mejor NO tener instancias extras por defecto del libro y simplemente añadirlas mediante el enlace Add another Book instance, o poder simplemente listar las BookInstances como enlaces no legibles desde aquí. La primera opción puede hacerse estableciendo el atributo extra a 0 en el modelo BookInstanceInline, inténtalo tú mismo.

+
+ +

Rétate a tí mismo

+ +

Hemos aprendido mucho en esta sección, así que es hora de que intentes algunas cosas.

+ +
    +
  1. Para la vista de lista de BookInstance, añade código para desplegar el libro, estado, fecha de devolución e id (en lugar del texto por defecto de __str__()).
  2. +
  3. Añade una lista encadenada de ítems Book (libros) a la vista detallada de Author usando el mismo método que usamos para Book/BookInstance.
  4. +
+ + + +

Resumen

+ +

¡Eso es todo! Ahora has aprendido cómo configurar el sito de administración tanto en su forma más simple como la mejorada, cómo crear un super usuario, y cómo navegar en el sitio de administración y ver, borrar y actualizar registros. Durante el proceso has creado un grupo de libros, instancias de libros, géneros y autores que seremos capaces de listar y desplegar una vez que creemos nuestras propias vistas y plantillas.

+ +

Siguientes lecturas

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}

+ +

 

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/authentication/index.html b/files/es/learn/server-side/django/authentication/index.html new file mode 100644 index 0000000000..af07915ad9 --- /dev/null +++ b/files/es/learn/server-side/django/authentication/index.html @@ -0,0 +1,714 @@ +--- +title: 'Tutorial de Django Parte 8: Autenticación y permisos de Usuario' +slug: Learn/Server-side/Django/Authentication +tags: + - Aprender + - Artículo + - Autenticacion de Django + - Autenticación + - Principiante + - Python + - Sesiones + - Tutorial + - django autenticación + - permisos +translation_of: Learn/Server-side/Django/Authentication +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}
+ +

En este tutorial mostraremos cómo permitir a los usuarios iniciar sesión en tu sitio con sus propias cuentas, y cómo controlar lo que pueden hacer basándose en si han iniciado sesión o no y sus permisos. Como parte de esta demostración extenderemos el sitio web de la BibliotecaLocal, añadiendo páginas de inicio y cierre de sesión, y páginas específicas de usuarios y personal de la biblioteca para ver libros que han sido prestados.

+ + + + + + + + + + + + +
Prerequisitos:Completa todos los temas del tutorial anterior, incluyendo: Django Tutorial Part 7: Sessions framework.
Objetivo:Comprender como configurar y usar la autenticación de usuario y los permisos.
+ +

Introducción

+ +

Django proporciona un sistema de autenticación y autorización ("permisos"), construido sobre el framework de sesión discutido en el tutorial anterior, que le permite verificar credenciales de usuario y definir que acciones puede realizar cada usuario. El framework incluye modelos para Users y Groups (una forma genérica de aplicar permisos a más de un usuario a la vez), permisos/indicadores (permissions/flags) que designan si un usuario puede realizar una tarea, formularios y vistas para iniciar sesión en los usuarios, y view tools para restringir el contenido.

+ +
+

Nota: Según Django el sistema de autenticación pretende ser muy genérico, y, por lo tanto,  no proporciona algunas características proporcinadas en otros sistemas de autenticación web. Las soluciones para algunos problemas están disponibles como paquetes de terceros. Por ejemplo, regulación de intentos de inicio de sesión y autenticación frente a terceros (por ej. OAuth).

+
+ +

En este tutorial mostraremos cómo habilitar la autenticación de usuarios en el sitio web BibliotecaLocal, crear tus propias páginas de login y logout, añadir permisos a tus modelos, y controlar el acceso a las páginas. Usaremos la autenticación/permisos para desplegar listas de libros que han sido solicitados tanto por los usuarios como por los bibliotecarios.

+ +

El sistema de autenticación es muy flexible, y puedes crear tus URLs, formularios, vistas y plantillas desde el inicio si quieres, simplemente llamando a la API provista para loguear al usuario. Sin embargo, en este artículo vamos a usar las vistas y formularios de autenticación "en stock" de Django para nuestras páginas de login y logout. De todos modos necesitaremos crear algunas plantillas, pero eso es bastante fácil.

+ +

Te mostraremos también cómo crear permisos, y revisar el estado de login y permisos tanto en vistas como en plantillas.

+ +

Habilitanto la autenticación

+ +

La autenticación fue habilitada automáticamente cuando creamos el sitio web esqueleto (en el tutorial 2), así que no necesitas hacer nada más en este punto.

+ +
+

Nota: Toda la configuración necesaria fue hecha por nosotros cuando creamos la aplicación usando el comando django-admin startproject. Las tablas de base de datos para los usuarios y permisos de modelo fueron creados la primera vez que ejecutamos python manage.py migrate.

+
+ +

La configuración se establece en las secciones INSTALLED_APPS y MIDDLEWARE del archivo del proyecto (locallibrary/locallibrary/settings.py), como se muestra abajo:

+ +
INSTALLED_APPS = [
+    ...
+    'django.contrib.auth',  #Core authentication framework and its default models.
+    'django.contrib.contenttypes',  #Django content type system (allows permissions to be associated with models).
+    ....
+
+MIDDLEWARE = [
+    ...
+    'django.contrib.sessions.middleware.SessionMiddleware',  #Manages sessions across requests
+    ...
+    'django.contrib.auth.middleware.AuthenticationMiddleware',  #Associates users with requests using sessions.
+    ....
+
+ +

Creando usuarios y grupos

+ +

Ya creaste tu primer usuario cuando revisamos el sitio de administración de Django en el tutorial 4 (fue un superusuario, creado con el comando python manage.py createsuperuser). Nuestro superusuario ya está autenticado y tiene todos los permisos, así que necesitaremos crear un usuario de prueba que represente un usuario normal del sitio. Estaremos usando el sitio de administración para crear los grupos y logins de nuestro sitio web BibliotecaLocal, ya que es una de las formas más rápidas de hacerlo.

+ +
+

Nota: Puedes también crear usuarios mediante programación, como se muestra abajo. Tendrías que hacerlo, por ejemplo, si estuvieras desarrollando una interfaz para permitir a los usuarios crear sus propios logins (no deberías dar a los usuarios acceso al sito de administración).

+ +
from django.contrib.auth.models import User
+
+# Create user and save to the database
+user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword')
+
+# Update fields and then save again
+user.first_name = 'John'
+user.last_name = 'Citizen'
+user.save()
+
+
+
+ +

A continuación, primero crearemos un grupo y luego un usuario. Aunque no tengamos ningún permiso aún para otorgar a los miembros de nuestra biblioteca, si lo necesitamos para más adelante, será mucho más fácil otorgarlo una vez al grupo que individualmente a cada miembro.

+ +

Inicia el servidor de desarrollo y navega hasta el sitio de administracion en tu navegador web local (http://127.0.0.1:8000/admin/). Ingresa al sitio usando las credenciales de la cuenta de tu superusuario. El nivel superior del sitio de administracion "Admin site" muestra todos tus modelos, ordenados por la aplicacion por defecto de Django "django application". Desde la seccion de Autenticación y Autorización puedes dar click en los enlaces de Usuarios "Users" y Grupos "Groups" para ver todos sus registros existentes.

+ +

Admin site - add groups or users

+ +

Primero vamos a crear un nuevo grupo para los miembros de nuestra biblioteca.

+ +
    +
  1. Da click en el boton Add "Añadir" (Enseguida de Group) para crear un nuevo grupo ; ingresa el Nombre "Name" para el grupo de "Library Members".Admin site - add group
  2. +
  3. No necesitamos de ningun permiso para el grupo , entonces solo presiona Save (Seras redirigido a una lista de los grupos disponibles).
  4. +
+ +

Ahora vamos a crear un usuario:

+ +
    +
  1. Navega de vuelta a la pagina de inicio "home" del sitio de administracion "Admin site".
  2. +
  3. Da click en el boton Add "Añadir" que queda enseguida de Users "Usuarios" para abrir el cuadro de dialogo de Usuario Add "Añadir usuario".Admin site - add user pt1
  4. +
  5. Ingresa un Nombre de Usuario "Username", Contraseña "Password" y Confirmacion de Contraseña "Password confirmation" apropiado para tu usuario de prueba.
  6. +
  7. Presiona Save "Guardar" para crear el usuario.
    +
    + El sitio de administrador creara el nuevo usuario e inmediatamente te llevara a la pantalla de Change user  "Cambios del usuario" donde puedes cambiar tu nombre de usuario "Username" y agregar informacion para los campos opcionales del modelo de Usuario "User". Estos campos incluyen el primer nombre "first name", el apellido "last name", la direcion de correo electronico "email adress", los estados de los usuarios y sus permisos "users status and permissions" (solo el indicador Active "Activo" deberia ser activado). Mas abajo puedes especificar los grupos y permisos del usuario, y ver datos importantes relacionados a el usuario (ej: la fecha en que se agrego y la fecha del ultimo inicio de sesion)
  8. +
  9. Admin site - add user pt2
  10. +
  11. En la seccion Groups "Grupos", selecciona el grupo Library Member de  la lista de grupos disponibles, y entonces presiona la la flecha apuntando a la derecha entre las dos cajas para moverlo dentro de la caja de Chosen groups "Grupos seleccionados".Admin site - add user to group
  12. +
  13. Aqui no necesitamos hacer nada adicional, entonces de nuevo solo seleciona SAVE "Guardar", para ir a la lista de usuarios.
  14. +
+ +

¡Esta hecho! Ahora tienes la cuenta de un miembro normal de la libreria, el cual estara disponible para ser usado en tus pruebas (una vez que hayamos implementado las paginas para permitirles iniciar sesion).

+ +
+

Nota: Deberias intentar crear otro usuario miembro de library.  Al igual que un grupo para los bibliotecarios "Librarians",  ¡y agregar usuarios a este tambien! 

+
+ +

Configurando nuestras vistas de autenticación

+ +

Django provee todo lo necesario para crear las páginas de autenticación para manejar inicio y cierre de sesión y gestión de contraseñas "fuera de la caja". Esto incluye un mapeador de URL, vistas "views" y formularios "forms", pero no incluye las plantillas "templates", ¡Tenemos que crear las nuestras!

+ +

En esta sección, mostramos cómo integrar el sistema por defecto en el sitio web de BibliotecaLocal y crear plantillas "templates". Las incluiremos en las URLs principales del proyecto.

+ +
+

Nota: No tienes que usar nada de este código, pero es probable que quieras hacerlo porque hace las cosas mucho más fáciles. Seguramente necesitará cambiar el código de manejo de formularios si cambia su modelo de usuario (¡un tema avanzado!) pero aun asi, todavía podrá usar las funciones de vista de stock.

+
+ +
+

Nota: En este caso podríamos razonablemente poner las páginas de autenticación, incluyendo las direcciones URL y plantillas, dentro de nuestra aplicación de catálogo. Sin embargo, si tuviéramos varias aplicaciones, sería mejor separar este comportamiento de inicio de sesión compartido y tenerlo disponible en todo el sitio, ¡así que eso es lo que hemos mostrado aquí!

+
+ +

URL's del proyecto

+ +

Añade el siguiente codigo al final del archivo url.py del proyecto (locallibrary/locallibrary/urls.py) :

+ +
#Add Django site authentication urls (for login, logout, password management)
+urlpatterns += [
+    path('accounts/', include('django.contrib.auth.urls')),
+]
+
+ +

Navega hasta la URL http://127.0.0.1:8000/accounts/ (¡Nota la barra inclinada hacia adelante!) y Django mostrara un error, diciendo que no puede encontrar esta URL, y listando todas las URL's que ha intentado. Aqui puedes ver las URL's que funcionaran, por ejemplo:

+ +
+

Nota: Usando el metodo anterior, añade las siguientes URL's con sus respectivos nombres entre corchetes, los cuales pueden ser usados para revertir "reverse" el mapeado de las URL's.  No necesitas implementar nada mas, el anterior mapeado de URL's asigna automaticamente las mencionadas URL's.

+
+ +
+
^accounts/login/$ [name='login']
+^accounts/logout/$ [name='logout']
+^accounts/password_change/$ [name='password_change']
+^accounts/password_change/done/$ [name='password_change_done']
+^accounts/password_reset/$ [name='password_reset']
+^accounts/password_reset/done/$ [name='password_reset_done']
+^accounts/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
+^accounts/reset/done/$ [name='password_reset_complete']
+
+ +

Ahora intenta navegar a la URL de inicio de sesion "login"(http://127.0.0.1:8000/accounts/login/). Esto fallara de nuevo, pero ahora con un error diciendote que no encuentra la plantilla "template" requerida (registration/login.html) por el buscador de directorios de plantillas . Veras el las siguientes lineas en la seccion amarilla en la parte superior:

+ +
Exception Type:    TemplateDoesNotExist
+Exception Value:    registration/login.html
+ +

El siguiente paso es crear un directorio de registro en la busqueda de directorios y entonces agregar el archivo login.html.

+ +

Directorio de plantilla "template"

+ +

Las URL's (y vistas "views" implicitas) que recien hemos añadido esperan encontrar sus plantillas "templates" asociadas en un directorio "/registration/" en algún lugar de la ruta de búsqueda de plantillas

+ +

Para este sitio pondremos nuestra pagina HTML en el directorio "templates/registration/". Este directorio debera estar en el directorio raiz de tu proyecto, es decir, el mismo directorio de las carpetas donde estan catalog locallibrary. Por favor ahora crea las carpetas "templates" y dentro de esta "registration".

+ +
+

Note: Your folder structure should now look like the below:
+ locallibrary (django project folder)
+    |_catalog
+    |_locallibrary
+    |_templates (new)
+                 |_registration

+
+ +

Para hacer estos directorios visibles al cargador de plantillas (es decir introducir este directorio en el buscador de directorios de plantillas) abre el archivo de configuracion del proyecto setting.py (/locallibrary/locallibrary/settings.py), y actualiza la seccion de TEMPLATES con la linea 'DIRS' como se muestra a continuacion.

+ +
TEMPLATES = [
+    {
+        ...
+        'DIRS': ['./templates',],
+        'APP_DIRS': True,
+        ...
+
+ +

Plantilla inicio de sesión "login"

+ +
+

Importante: Las plantillas de autenticacion provista en este articulo son versiones muy basicas y ligeramete modificadas de las plantillas de inicio de sesion de demostracion de Django. ¡Necesitas personalizarlos para tus propios usos!

+
+ +

Crea un nuevo archivo HTML llamado /locallibrary/templates/registration/login.html. suministrado en el siguiente contenido :

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+{% if form.errors %}
+<p>Your username and password didn't match. Please try again.</p>
+{% endif %}
+
+{% if next %}
+    {% if user.is_authenticated %}
+    <p>Your account doesn't have access to this page. To proceed,
+    please login with an account that has access.</p>
+    {% else %}
+    <p>Please login to see this page.</p>
+    {% endif %}
+{% endif %}
+
+<form method="post" action="{% url 'login' %}">
+{% csrf_token %}
+
+<div>
+  <td>\{{ form.username.label_tag }}</td>
+  <td>\{{ form.username }}</td>
+</div>
+<div>
+  <td>\{{ form.password.label_tag }}</td>
+  <td>\{{ form.password }}</td>
+</div>
+
+<div>
+  <input type="submit" value="login" />
+  <input type="hidden" name="next" value="\{{ next }}" />
+</div>
+</form>
+
+{# Assumes you setup the password_reset view in your URLconf #}
+<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
+
+{% endblock %}
+ +

Estas plantillas comparten algunas similitudes con algunas que hemos visto antes — extiende nuestra plantilla base y sobreescribe el bloque content. El resto del código es un código de manejo de formularios bastante estándar, que trataremos en un tutorial posterior. Todo lo que necesitas saber por ahora es que esto mostrará un formulario en el que puedes introducir tu usuario y contraseña, y que si introduces valores inválidos se te pedirá que ingreses los valores correctos cuando la página refresque.

+ +

Navega de vuelta a la página de inicio sesión (http://127.0.0.1:8000/accounts/login/) una vez que hayas guardado tu plantilla, y deberías ver algo como esto:

+ +

Library login page v1

+ +

Si intentas iniciar sesión tendrá éxito y serás redirigido a otra página (por defecto será http://127.0.0.1:8000/accounts/profile/). El problema aquí es que, por defecto, Django espera que después de iniciar sesión seas llevado a una página de perfil (que podrá ser el caso o no). Como no has definido esta página todavía, ¡obtendrás otro error!

+ +

Abre la configuración del proyecto (/locallibrary/locallibrary/settings.py) y añade al final el texto de abajo. Ahora cuando inicies sesión deberías ser redirigido a la página de inicio por defecto.

+ +
# Redirect to home URL after login (Default redirects to /accounts/profile/)
+LOGIN_REDIRECT_URL = '/'
+
+ +

Plantilla cierre de sesión "logout"

+ +

Si navegas a la url de cierre de sesión (http://127.0.0.1:8000/accounts/logout/) verás un extraño comportamiento — tu usuario cerrará la sesión, pero serás llevado a la página de cierre de sesión del Administrador. Eso no es lo que quieres, aunque sólo sea porque el enlace de inicio de sesión de esa página te lleva a la pantalla del inicio de sesión del Administrador (y eso sólo está disponible a los usuarios que tienen el permiso is_staff).

+ +

Crea y abre el fichero /locallibrary/templates/registration/logged_out.html. Copia en él el siguiente texto:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<p>Logged out!</p>
+
+<a href="{% url 'login'%}">Click here to login again.</a>
+{% endblock %}
+ +

Esta plantilla es muy simple. Tan sólo muestra un mensaje informándote que has cerrado sesión, y provee un enlace que puedes pulsar para volver a la página de inicio de sesión. Si vas a la url de cierre de sesión otra vez, deberías ver esta página:

+ +

Library logout page v1

+ +

Plantillas de reinicio de contraseña "Password reset"

+ +

El sistema de reinicio de contraseña usa el correo electrónico para enviar al usuario un enlace de reinicio. Necesitas crear formularios para obtener la dirección de correo electrónico del usuario, enviar el correo, permitirle introducir una nueva contraseña y tenerla en cuenta cuando todo el proceso se haya completado.

+ +

Las siguientes plantillas pueden usarse como un punto de partida.

+ +

Formulario de reinicio de contraseña

+ +

Este es el formulario para obtener la dirección del correo electrónico del usuario (para enviar el correo de reinicio de contraseña). Crea /locallibrary/templates/registration/password_reset_form.html, y establece el siguiente contenido:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+
+<form action="" method="post">{% csrf_token %}
+    {% if form.email.errors %} \{{ form.email.errors }} {% endif %}
+        <p>\{{ form.email }}</p>
+    <input type="submit" class="btn btn-default btn-lg" value="Reset password" />
+</form>
+
+{% endblock %}
+
+ +

Reinicio de contraseña hecho

+ +

Este formulario es mostrado después de que tu dirección de correo electrónico haya sido recogida. Crea /locallibrary/templates/registration/password_reset_done.html, y establece el siguiente contenido:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
+{% endblock %}
+
+ +

Correo electrónico de reinicio de contraseña

+ +

Esta plantilla suministra el texto HTML del correo electrónico, y contiene el enlace de reseteo que enviaremos a los usuarios. Crea /locallibrary/templates/registration/password_reset_email.html, y establece el siguiente contenido:

+ +
Someone asked for password reset for email \{{ email }}. Follow the link below:
+\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
+
+ +

Confirmación de reinicio de contraseña

+ +

Esta página es donde introduces una nueva contraseña después de pinchar el enlace en el correo electrónico de reinicio de contraseña. Crea /locallibrary/templates/registration/password_reset_confirm.html, y establece el siguiente contenido:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+    {% if validlink %}
+        <p>Please enter (and confirm) your new password.</p>
+        <form action="" method="post">
+            <div style="display:none">
+                <input type="hidden" value="\{{ csrf_token }}" name="csrfmiddlewaretoken">
+            </div>
+            <table>
+                <tr>
+                    <td>\{{ form.new_password1.errors }}
+                        <label for="id_new_password1">New password:</label></td>
+                    <td>\{{ form.new_password1 }}</td>
+                </tr>
+                <tr>
+                    <td>\{{ form.new_password2.errors }}
+                        <label for="id_new_password2">Confirm password:</label></td>
+                    <td>\{{ form.new_password2 }}</td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td><input type="submit" value="Change my password" /></td>
+                </tr>
+            </table>
+        </form>
+    {% else %}
+        <h1>Password reset failed</h1>
+        <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
+    {% endif %}
+
+{% endblock %}
+
+ +

Reinicio de contraseña completado

+ +

Este es el último paso de la plantilla de reinicio de contraseña, que es mostrada para notificarte cuando el reinicio de contraseña ha tenido éxito. Crea /locallibrary/templates/registration/password_reset_complete.html, y establece el siguiente contenido:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+
+<h1>The password has been changed!</h1>
+<p><a href="{% url 'login' %}">log in again?</a></p>
+
+{% endblock %}
+ +

Probando las nuevas páginas de autenticación

+ +

Ahora que has añadido la configuración URL y creado todas estas plantillas, ¡las páginas de autenticación ahora deberían funcionar!

+ +

Puedes probar las nuevas páginas de autenticación intentando iniciar sesión y entonces cerrar sesión con tu cuenta de super administrador usando estas URLs:

+ + + +

Serás capaz de probar la funcionalidad de reinicio de contraseña desde el enlace de la página de inicio de sesión. ¡Ten cuidado con el hecho de que Django solamente enviará correos de reinicio a las direcciones (usuarios) que ya están almacenadas en la base de datos!

+ +
+

Nota: El sistema de reinicio de contraseña requiere que tu sitio web soporte envío de correo, que está más allá del ámbito de este artículo, por lo que esta parte no funcionará todavía. Para permitir el testeo, establece la siguiente línea al final de tu fichero settings.py. Esto registra en la consola cualquier envío de correo electrónico (y así puedes copiar el enlace de reinicio de contraseña desde dicha consola).

+ +
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+
+ +

Para más información, ver Sending email (Django docs).

+
+ +

Probando contra usuarios autenticados

+ +

Esta sección mira a lo que podemos hacer para controlar selectivamente el contenido que el usuario ve basado en si ha iniciado sesión o no.

+ +

Probando en plantillas

+ +

Puedes obtener información en las plantillas sobre el usuario que actualmente ha iniciado sesión con la variable de plantillas \{{ user }} (esto se añade por defecto al contexto de la plantilla cuando configuras el proyecto como hicimos en nuestro esqueleto).

+ +

Es típico que primero pruebes con la variable de plantilla \{{ user.is_authenticated }} para determinar si el usuario puede ver el contenido específico. Para demostrar esto, lo siguiente que haremos será actualizar nuestra barra lateral "sidebar" para mostrar un enlace de inicio de sesión "Login" si el usuario no ha iniciado sesión, y un cierre de sesión "Logout" en el caso de que sí la haya iniciado.

+ +

Abre la plantilla base (/locallibrary/catalog/templates/base_generic.html) y copia el siguiente texto en el bloque sidebar, justamente antes de la etiqueta de plantilla endblock .

+ +
  <ul class="sidebar-nav">
+
+    ...
+
+   {% if user.is_authenticated %}
+     <li>User: \{{ user.get_username }}</li>
+     <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
+   {% else %}
+     <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
+   {% endif %} 
+  </ul>
+ +

Como puedes ver, usamos las etiquetas de plantilla if-else-endif para condicionar el texto mostrado basado en si \{{ user.is_authenticated }} es cierto o no. Si el usuario está autenticado, sabemos que tenemos un usuario válido, por lo que llamamos a \{{ user.get_username }} para mostrar su nombre.

+ +

Creamos los enlaces URLs del inicio y del cierre de sesión usando la etiqueta de plantilla url y los nombres de las respectivas configuraciones de las URL. Nótese también cómo hemos añadido ?next=\{{request.path}} al final de las URLs. Lo que esto hace es añadir el párametro URL next que contiene la dirección (URL) de la página actual, al final de la URL enlazada. Después de que el usuario haya iniciado o cerrado sesión con éxito, las vistas usarán el valor de este "next" para redirigir al usuario de vuelta a la página donde pincharon primeramente el enlace de inicio/cierre de sesión.

+ +
+

Nota: ¡Pruébalo! Si estás en la página de inicio y pinchas en la barra lateral "sidebar", después de que la operación se complete deberías acabar de vuelta en la misma página.

+
+ +

Probando en vistas

+ +

Si estás usando vistas basadas en funciones, la forma más facil para restringir el acceso a tus funciones es aplicar el decorador login_required a tu función de vista, como se muestra más abajo. Si el usuario ha iniciado sesión entonces tu código de vista se ejecutará como normalmente lo hace. Si el usuario no ha iniciado sesión, se redirigirá a la URL de inicio de sesión definida en tu configuración de proyecto (settings.LOGIN_URL), pasando el directorio absoluto actual como el parámetro URL next. Si el usuario tiene éxito en el inicio de sesión entonces será devuelto a esta página, pero esta vez autenticado.

+ +
from django.contrib.auth.decorators import login_required
+
+@login_required
+def my_view(request):
+    ...
+ +
+

Nota: ¡Tú puedes hacer el mismo tipo de cosas manualmente probando con request.user.is_authenticated, pero el decorador es mucho más conveniente!

+
+ +

De manera similar, la forma más fácil de restringir el acceso a los usuarios que han iniciado sesión en tus vistas basadas en clases es extender de LoginRequiredMixin. Necesitas declarar primeramente este mixin en la lista de super clases, antes de la clase de vista principal.

+ +
from django.contrib.auth.mixins import LoginRequiredMixin
+
+class MyView(LoginRequiredMixin, View):
+    ...
+ +

Esto tiene exactamente el mismo comportamiento de redirección que el decorador login_required. También puedes especificar una localización alternativa para redirigir al usuario si no están autenticados (login_url), y un nombre de parámetro URL en lugar de "next" para insertar el directorio absoluto actual (redirect_field_name).

+ +
class MyView(LoginRequiredMixin, View):
+    login_url = '/login/'
+    redirect_field_name = 'redirect_to'
+
+ +

Para detalles adicionales, echa un vistazo a Django docs.

+ +

Ejemplo - listando los libros del usuario actual

+ +

Ahora que sabemos cómo restringir una página a un usuario concreto, vamos a crear una vista de los libros que el usuario tiene prestados actualmente.

+ +

Desafortunadamente, ¡todavía no tenemos una forma de pedir prestados los libros a los usuarios! Por eso, antes de que podamos crear la lista de libros vamos primeramente a extender el modelo BookInstance para dar soporte al concepto de pedir prestado y usar la aplicación del Administrador Djando para alquilar un número de libros a nuestro usuario de prueba.

+ +

Modelos

+ +

Primero vamos a hacer posible para los usuarios tener una BookInstance en alquiler (ya tenemos un status y una fecha due_back, pero no tenemos todavía una asociación entre este modelo y un Usuario). Crearemos uno usando un campo ForeignKey (uno-a-muchos). También necesitaremos un mecanismo sencillo para probar si un libro alquilado está atrasado.

+ +

Abre catalog/models.py, e importa el modelo User de django.contrib.auth.models (añade esto justamente debajo de la anterior línea de importación, arriba del todo del fichero, para que el User esté disponible para el posterior código del que hace uso):

+ +
from django.contrib.auth.models import User
+
+ +

Después añade el campo borrower al modelo BookInstance:

+ +
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
+
+ +

Ya que estamos aquí, vamos a añadir una propiedad que podamos llamar desde nuestras plantillas para decir si una instancia particular de un libro está atrasada. Mientras que podríamos calcular esto en la misma plantilla, usar una propiedad (property) como se muestra abajo será mucho más eficiente.

+ +
from datetime import date
+
+@property
+def is_overdue(self):
+    if self.due_back and date.today() > self.due_back:
+        return True
+    return False
+ +
+

Nota: Primeramente verificamos si la fecha due_back está vacía antes de realizar una comparación. Un campo vacío due_back provocaría a Django arrojar un error en lugar de mostrar la página: los valores vacíos no son comparables. ¡Esto no es algo que queramos para la experiencia de nuestros usuarios!

+
+ +

Ahora que hemos actualizado nuestros modelos, necesitaremos hacer migraciones actuales en el proyecto y entonces aplicar esas migraciones:

+ +
python3 manage.py makemigrations
+python3 manage.py migrate
+
+ +

Administrador

+ +

Ahora abre catalog/admin.py, y añade el campo borrower a la clase BookInstanceAdmin en ambas list_displayfieldsets como se muestra abajo. Esto hará el campo visible en la sección de Administrador, por lo que podemos asignar un User a una BookInstance cuando lo necesitemos.

+ +
@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    list_display = ('book', 'status', 'borrower', 'due_back', 'id')
+    list_filter = ('status', 'due_back')
+
+    fieldsets = (
+        (None, {
+            'fields': ('book','imprint', 'id')
+        }),
+        ('Availability', {
+            'fields': ('status', 'due_back','borrower')
+        }),
+    )
+ +

Alquilar unos pocos libros

+ +

Ahora que es posible alquilar libros a un usuario específico, ve y alquila un número de registros BookInstance. Establece su campo borrowed a tu usuario de prueba, establece el status "On loan" (en alquiler) y establece fechas de vencimiento tanto en el futuro como en el pasado.

+ +
+

Nota: No escribiremos el proceso, porque ¡ya sabes cómo usar el sitio de Administrador!

+
+ +

Vista en alquiler

+ +

Ahora añadiremos una vista para obtener la lista de todos los libros que han sido alquilados al usuario actual. Usaremos la misma vista de lista genérica basada en clases con la que estamos familiarizada, pero esta vez también importaremos y extenderemos de LoginRequiredMixin, por lo que solamente un usuario que ha iniciado sesión podrá llamar a esta vista. También elegiremos declarar una template_name en lugar de usar la de por defecto, porque quizás acabemos teniendo unas pocas listas diferentes de registros de BookInstance, con diferentes vistas y plantillas.

+ +

Añade lo siguiente a catalog/views.py:

+ +
from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
+    """
+    Generic class-based view listing books on loan to current user.
+    """
+    model = BookInstance
+    template_name ='catalog/bookinstance_list_borrowed_user.html'
+    paginate_by = 10
+
+    def get_queryset(self):
+        return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
+ +

Para restringir nuestra consulta a solamente los objetos BookInstance del usuario actual, vamos a reimplementar get_queryset() como se muestra abajo. Nótese que "o" es el código almacenado para "on loan" (en alquiler) y vamos a ordenar por la fecha due_back para que los elementos más antiguos se muestren primero.

+ +

Configuración URL para libros alquilados

+ +

Ahora abre /catalog/urls.py y añade la url url() apuntando a la vista anterior (puedes simplemente copiar el texto de abajo al final del fichero).

+ +
urlpatterns += [
+    url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
+]
+ +

Plantilla para libros alquilados

+ +

Ahora todo lo que necesitamos hacer para esta página es añadir una plantilla. Primero, creamos el fichero plantilla /catalog/templates/catalog/bookinstance_list_borrowed_user.html y establecemos el siguiente contenido en ella:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+    <h1>Borrowed books</h1>
+
+    {% if bookinstance_list %}
+    <ul>
+
+      {% for bookinst in bookinstance_list %}
+      <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
+        <a href="{% url 'book-detail' bookinst.book.pk %}">\{{bookinst.book.title}}</a> (\{{ bookinst.due_back }})
+      </li>
+      {% endfor %}
+    </ul>
+
+    {% else %}
+      <p>There are no books borrowed.</p>
+    {% endif %}
+{% endblock %}
+ +

Esta plantilla es muy similar a esas que hemos creado previamente para los objetos Book y Author. La única "cosa" nueva aquí es que comprobamos el método que hemos añadido en el modelo (bookinst.is_overdue) y lo usamos para cambiar el color de los elementos atrasados.

+ +

Cuando el servidor de desarrollo esté en ejecución, deberías ser capaz de ver la lista de los usuarios que han iniciado sesión en tu navegador en http://127.0.0.1:8000/catalog/mybooks/. Prueba esto con tu usuario iniciado en la sesión y cerrado en la sesión (en el segundo caso, deberías ser redirigido a la página de inicio).

+ +

Añadir la lista a la barra lateral

+ +

El último paso es añadir un enlace para esta nueva página en la barra lateral "sidebar". Pondremos esto en la misma sección donde mostramos otra información para el usuario que ha iniciado la sesión.

+ +

Abre la plantilla base (/locallibrary/catalog/templates/base_generic.html) y añade la línea en negrita a la barra lateral como se muestra.

+ +
 <ul class="sidebar-nav">
+   {% if user.is_authenticated %}
+   <li>User: \{{ user.get_username }}</li>
+   <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
+   <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li>
+   {% else %}
+   <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li>
+   {% endif %}
+ </ul>
+
+ +

¿Cómo se ve?

+ +

Cuando cualquier usuario ha iniciado sesión, verán el enlace My Borrowed (Mis Alquileres) en la barra lateral, y la lista de libros mostrados como se ve abajo (¡el primer libro no tiene fecha de vencimiento, que es un bug que esperamos arreglar en un tutorial posterior!).

+ +

Library - borrowed books by user

+ +

Permisos

+ +

Los permisos están asociados con los modelos, y definen las operaciones que pueden llevarse a cabo en un modelo instanciado por un usuario que tiene el permiso. Por defecto, Django automáticamente da los permisos add, change, and delete (añadir, cambiar y eliminar) a todos los modelos, que permiten a los usuarios con los permisos realizar las acciones asociadas a través del sitio de Administrador. Tú puedes definir tus propios permisos a los modelos y concedérselos a usuarios específicos. También puedes cambiar los permisos asociados con diferentes instancias del mismo modelo.

+ +

Probar permisos en vistas y plantillas es muy similar a probar sobre el estado de autenticación (y, de hecho, probar un permiso también prueba una autenticación).

+ +

Modelos

+ +

La definición de permisos está hecha en la sección del modelo "class Meta", usando el campo permissions. Puedes especificar tantos permisos como necesites en una tupla, cada permiso está definido a sí mismo en una tupla anidada que contiene el nombre del permiso y el valor mostrado del mismo. Por ejemplo, podríamos definir un permiso para permitir a un usuario marcar un libro que ya ha sido devuelto, como se muestra:

+ +
class BookInstance(models.Model):
+    ...
+    class Meta:
+        ...
+        permissions = (("can_mark_returned", "Set book as returned"),)   
+ +

Podríamos asignar el permiso a un grupo bibliotecario "Librarian" en el sitio de Administración.

+ +

Abre catalog/models.py, y añade el permiso como se muestra arriba. Necesitarás volver a ejecutar tus migraciones (ejecutar python3 manage.py makemigrations y python3 manage.py migrate) para actualizar la base de datos de forma apropiada.

+ +

Plantillas

+ +

Los permisos del usuario actual están almacenados en una variable de plantilla llamada \{{ perms }}. Puedes comprobar si el usuario actual tiene un permiso particular usando el nombre de variable específico con la "app" asociada en Django — ej. \{{ perms.catalog.can_mark_returned }} será True (cierto) si el usuario tiene el permiso, y False (falso) en otro caso. De forma típica probamos el permiso usando la etiqueta de plantilla {% if %} como se muestra:

+ +
{% if perms.catalog.can_mark_returned %}
+    <!-- We can mark a BookInstance as returned. -->
+    <!-- Perhaps add code to link to a "book return" view here. -->
+{% endif %}
+
+ +

Vistas

+ +

Los permisos pueden ser probados en una vista de función usando el decorador permission_required o en una vista basada en clases usando el PermissionRequiredMixin. El patrón y el comportamiento son los mismos que para la autenticación de inicio de sesión, aunque desde luego podrías razonablemente tener que añadir múltiples permisos.

+ +

Decorador de vista de funciones:

+ +
from django.contrib.auth.decorators import permission_required
+
+@permission_required('catalog.can_mark_returned')
+@permission_required('catalog.can_edit')
+def my_view(request):
+    ...
+ +

"Mixin" de permisos requeridos para vistas basadas en clases:

+ +
from django.contrib.auth.mixins import PermissionRequiredMixin
+
+class MyView(PermissionRequiredMixin, View):
+    permission_required = 'catalog.can_mark_returned'
+    # Or multiple permissions
+    permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
+    # Note that 'catalog.can_edit' is just an example
+    # the catalog application doesn't have such permission!
+ +

Ejemplo

+ +

Nosotros no actualizaremos la LocalLibrary aquí; ¡quizás en el siguiente tutorial!

+ +

Desafíate a ti mismo

+ +

Anteriormente en este artículo te mostramos cómo crear una página para el usuario actual para listar los libros que había pedido prestado. El desafío ahora es crear una página similar que solamente sea visible para los bibliotecarios, que muestre todos los libros que hayan sido prestados, y que incluya el nombre de cada prestatario.

+ +

Deberías ser capaz de seguir el mismo patrón que el de la otra vista. La principal diferencia es que necesitarás restringir la vista a solamente los bibliotecarios. Podrías hacer esto basándote en si es un miembro de los empleados (decorador de función: staff_member_required, variable de plantilla: user.is_staff) pero nosotros te recomendamos que en su lugar uses el permiso can_mark_returned y PermissionRequiredMixin, como se describe en la sección anterior.

+ +
+

Importante: Recuerda no usar tu súper usuario para pruebas basadas en permisos (la comprobación de permisos siempre devuelve cierto para súper usuarios, ¡incluso si un permiso no ha sido definido todavía!). En su lugar, crea un usuario bibliotecario, y añade entonces la capacidad requerida.

+
+ +

Cuando hayas terminado, tu página debería verse algo parecida a la captura de pantalla de abajo.

+ +

All borrowed books, restricted to librarian

+ + + +

Sumario

+ +

Excelente trabajo — has creado un sitio web para que los miembros de la biblioteca puedan iniciar sesión y ver su propio contenido, y los bibliotecarios (con el permiso correcto) puedan usarlo para ver todos los libros alquilados y sus prestatarios. En este momento estamos todavía simplemente viendo contenido, pero los mismos principios y técnicas son usados cuando empiezas a modificar y añadir datos.

+ +

En nuestro siguiente artículo observaremos cómo puedes usar los formularios de Django para recoger la entrada de datos del usuario, y entonces empezar a modificar algunos de nuestros datos almacenados.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + + +
+
+
diff --git a/files/es/learn/server-side/django/deployment/index.html b/files/es/learn/server-side/django/deployment/index.html new file mode 100644 index 0000000000..ddcb7f5c4e --- /dev/null +++ b/files/es/learn/server-side/django/deployment/index.html @@ -0,0 +1,672 @@ +--- +title: 'Tutorial de Django Parte 11: Desplegando Django a producción' +slug: Learn/Server-side/Django/Deployment +translation_of: Learn/Server-side/Django/Deployment +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}
+ +

Ahora que has creado (y probado) un fantastico sitio web para la Biblioteca Local, querrás instalarlo en un servidor web público de manera que pueda ser accedido por el personal y los miembros de la biblioteca a través de Internet. Este artículo proporciona una visión general de cómo buscar un host para desplegar tu sitio web y de lo que necesitas hacer para conseguir que tu sitio esté listo en producción.

+ + + + + + + + + + + + +
Requisitos previos:Completar todos los tutoriales de los temas previos, incluyendo Django Tutorial Part 10: Testing a Django web application.
Objetivo:Aprender ¿cómo? y ¿dónde? puedes puedes desplegar una app de Django en producción.
+ +

Introducción

+ +

Una vez que tu sitio este terminado (o lo suficientemente terminado como para iniciar una prueba pública) vas a necesitar alojarla en un lugar más público y accesible que tu computadora personal.

+ +

Hasta ahora has estado trabajando en un entorno de desarrollo, usando Django development web server para compartir tu sitio con el navegador/red local, y corriendo tu sitio web con configuraciones (inseguras) de desarrollo que exponen la depuración y otra informacion privada. Antes de que puedas alojar tu sitio web externamente, lo primero que tendrás que hacer es:

+ + + +

Este tutorial provee una guía de opciones para elegir un sitio de alojamiento, una breve descripción general de lo que necesitas hacer para preparar tu aplicación Django en producción, y un ejemplo práctico de cómo instalar el sitio web de LocalLibrary en el servicio de alojamiento en la nube de Heroku.

+ +

¿Qué es un entorno de producción?

+ +

El entorno de producción es el entorno proporcionado por el servidor en el que correrá su sitio web para uso externo. El entorno incluye:

+ + + +
+

Nota: Dependiendo de como esté configurado su entorno de producción, usted podría disponer también de un proxy inverso, balanceador de carga, etc.

+
+ +

El servidor podría estar ubicado en sus propias instalaciones y conectado a Internet a través de un enlace rápido, pero lo más común es utilizar un computador alojado "en la nube". Esto en realidad implica que su código es ejecutado en algún computador remoto (o posiblemente un computador "virtual") en el centro (o centros) de datos de su compañía de servicios de hosting. El servidor remoto normalmente ofrecerá un determinado nivel garantizado de recursos de computación (es decir, CPU, RAM, memoria de almacenamiento, etc) y de conectividad a Internet por un cierto precio.

+ +

A este tipo de hardware de computación/comunicaciones accesible de forma remota se le denomina Infrastructure as a Service o Infraestructura como Servicio (IaaS). Muchos proveedores de IaaS ofrecen la opción de preinstalar un sistema operativo en particular, sobre el cual se debe instalar el resto de componentes de su entorno de producción. Otros permiten seleccionar entornos plenamente configurados, con incluso configuraciones de Django y servidor web establecidas.

+ +
+

Nota: Los entornos pre-construidos le permiten establecer su sitio web de manera muy sencilla, ya que reducen el trabajo de configuración, pero las opciones disponibles podrían limitarle al uso de un servidor (u otros componentes) poco conocido, o podrían estar basados en versiones antiguas del Sistema Operativo. A menudo es preferible que uno mismo instale sus propios componentes, de manera que disponga de los que desee, y en el momento que necesite subir el nivel de prestaciones de alguna parte del sistema, tener cierta idea de por dónde empezar

+
+ +

Otros proveedores de hosting incluyen Django como parte de una Plataform as a Service o Plataforma como Servicio (PaaS). En este tipo de hosting no necesita preocuparse de la mayor parte del entorno de producción (servidor web, servidor de aplicaciones, balanceadores de carga), dado que la plataforma host ya se ocupa de todo ello por usted (así como de casi todo lo necesario para escalar su aplicación). Esto hace el despliegue bastante sencillo, puesto que ya solo necesita concentrarse en su aplicación web y no en el resto de la infraestructura de servidor.

+ +

Algunos desarrolladores elegirán la mayor flexibilidad ofrecida por una IaaS frente a una PaaS, mientras que otros valorarán el reducido coste general de mantenimiento y la mayor facilidad de escalado de PaaS. Cuando se está empezando, la instalación del sitio web en un sistema PaaS es mucho más sencilla, así que eso es lo que haremos en este tutorial. 

+ +
+

Consejo: Si eliges un proveedor de hosting adaptado a Python/Django, éste debería facilitar instrucciones de cómo instalar un sitio web Django usando diferentes configuraciones de servidor web, servidor de aplicaciones, proxy inverso, etc (esto es irrelevante si eliges una PaaS). Por ejemplo, existen muchas guías paso-a-paso para distintas configuraciones en la Digital Ocean Django community docs.

+
+ +

Eligiendo un proveedor de hosting

+ +

Existen más de 100 proveedores de hosting de los que se sabe que, o bien dan soporte activo, o funcionan bien con Django (puedes encontrar una lista bastante extensa en Djangofriendly hosts). Estos proveedores proporcionan diferentes tipos de entornos (IaaS, PaaS), así como diferentes niveles de recursos de computación y comunicaciones a diferentes precios.

+ +

Algunos aspectos a considerar al elegir un host son:

+ + + +

La buena noticia cuando estás en los comienzos es que existen bastantes sitios que proporcionan entornos de computación de "evaluación", "desarrollo" o "de nivel aficionado" de forma gratuita. Se trata siempre de entornos bastantes limitados/restringidos en recursos, y debes estar precavido en que pueden expirar al cabo de un periodo de introducción. Son, no obstante, muy útiles para probar sitios con poco tráfico en un entorno real, y pueden proporcionar una migración sencilla contratando más recursos si el sitio alcanza más ocupación. Entre las opciones conocidas de esta categoría tenemos Heroku, Python Anywhere, Amazon Web Services, Microsoft Azure, etc. 

+ +

Muchos proveedores disponen también de un nivel "básico" que proporciona niveles de capacidad de computación más útiles y con menos limitaciones. Digital Ocean y Python Anywhere son ejemplos de proveedores populares de hosting que ofrecen niveles básicos de computación relativamente baratos (en el rango de los 5 a los 10 $USD mensuales).

+ +
+

Nota:  Recuerda que el precio no es el único criterio de selección. Si tu sitio web tiene éxito, la escalabilidad puede convertirse en la consideración más importante.

+
+ +

Preparando tu sitio web para hacerlo público

+ +

La Django skeleton website creada usando las herramientas django-admin y manage.py están configuradas para hacer más sencillo el desarrollo. Muchos de los ajustes del proyecto Django (especificados en settings.py) deberían ser distintos en producción, por razones tanto de seguridad como de rendimiento.

+ +
+

Consejo: Es bastante común disponer de un archivo settings.py separado en producción, e importar los ajustes sensibles desde un archivo aparte o desde una variable de entorno. Este archivo debería, por tanto, estar protegido, aún cuando el resto del código fuente esté disponible en un repositorio público.

+
+ +

Los ajustes críticos que debes comprobar son:

+ + + +

Modifiquemos la aplicación LocalLibrary de manera que leamos nuestras variables SECRET_KEY y DEBUG desde variables de entorno si han sido definidas o, en otro caso, usar los valores por defecto del archivo de configuración.

+ +

Abra /locallibrary/settings.py, deshabilite la configuración original de l SECRET_KEY y añada las nuevas líneas tal como se muestran abajo en negrita. Durante el desarrollo no se especificará ninguna variable de entorno para la clave, por lo que se usará el valor por defecto (no debería importar qué clave utilizas aquí, o si la clave tiene "fugas", dado que no la utilizarás en producción).

+ +
# SECURITY WARNING: keep the secret key used in production secret!
+# SECRET_KEY = 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag'
+import os
+SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag')
+
+ +

A continuación, comenta el ajuste de DEBUG existente y añade la nueva línea que se muestra abajo.

+ +
# SECURITY WARNING: don't run with debug turned on in production!
+# DEBUG = True
+DEBUG = bool( os.environ.get('DJANGO_DEBUG', True) )
+
+ +

El valor de DEBUG será True por defecto, pero será False si el valor de la variable de entorno DJANGO_DEBUG se establece como una cadena vacía, es decir, DJANGO_DEBUG=''.

+ +
+

Nota: Sería más intuitivo si pudiéramos simplemente marcar y desmarcar la variable de entorno DJANGO_DEBUG a TrueFalse directamente, en lugar de usar "cualquier cadena" o "cadena vacía" (respectivamente). Por desgracia, los valores de las variables de entorno son almacenados como cadenas de Python (Python strings), y la única cadena que se evalúa como False es la cadena vacía (por ejemplo, bool('')==False).

+
+ +

Deployment checklist (Django docs) proporciona una lista de comprobación completa de ajustes que podrías querer cambiar. Puedes también sacar una lista de algunos de ellos usando el siguiente comando de terminal:

+ +
python3 manage.py check --deploy
+
+ +

Ejemplo: Instalando LocalLibrary en Heroku

+ +

Esta sección aborda una demostración práctica de cómo instalar LocalLibrary en Heroku PaaS cloud.

+ +

¿Por qué Heroku?

+ +

Heroku es uno de los servicios PaaS basados en la nube más duraderos y conocidos. Originalmente únicamente daba soporte a aplicaciones Ruby, pero actualmente puede utilizarse para aplicaciones host de muchos entornos de programación, incluido Django!

+ +

Vamos a elegir Heroku por varias razones:

+ + + +

Si bien Heroku es perfecto para alojar esta demostración, puede no serlo para tu sitio web real. Heroku facilita la instalación y el escalado, a costa de ser menos flexible, y potencialmente mucho más caro una vez que abandonas el nivel gratuito.

+ +

¿Cómo funciona Heroku?

+ +

Heroku ejecuta sitios web Django dentro de uno o más "Dynos", que son contenedores Unix virtualizados y aislados que proporcionan el entorno necesario para ejecutar una aplicación. Los dynos están completamente aislados y disponen de un sistema de archivos efímero (sistema de archivos de vida corta que es limpiado/vaciado cada vez que el dyno se reinicia). Lo único que los dynos comparten por defecto son las variables de configuración (configuration variables) de las aplicaciones. Heroku utiliza interrnamente un balanceador de carga para distribuir el tráfico web entre todas las dynos "web". Puesto que no se comparte nada entre ellas, Heroku puede escalar una app horizontalmente simplemente añadiendo más dynos (aunque, claro está, podrías necesitar escalar tu base de datos para aceptar conexiones adicionales).

+ +

Puesto que el sistema de archivos es efímero, no puedes instalar los servicios requeridos por tu aplicación directamente (por ejemplo, bases de datos, colas, sistemas de cacheado, almacenamiento, servicios de correo electrónico, etc). En su lugar, las aplicaciones web de Heroku usan servicios de respaldo proporcionados por Heroku o terceros como "add-ons" independientes. Una vez adjuntados a tu aplicación web, los dynos acceden a los servicios usando la información contenida en las variables de configuración de la aplicación.

+ +

Para ejecutar tu aplicación, Heroku necesita poder instalar el entorno y las dependencias adecuados, y entender cómo están enlazados. Para las apps Django, esta información se proporciona en una serie de archivos de texto:

+ + + +

Los desarrolladores interactúan con Heroku usando una app/terminal cliente especial, algo muy parecido a un bash script de Unix. Esto permite subir código almacenado en un repositorio git, inspeccionar los procesos en ejecución, ver logs, establecer variables de configuración, y mucho más!.

+ +

Para conseguir nuestra aplicación para trabajar en Heroku, necesitaremos colocar nuestra aplicación web Django dentro de un repositorio git, añadir los archivos anteriores, integrar con una base de datos add-on, y hacer cambios para manejar correctamente los archivos estáticos.

+ +

Una vez hecho todo eso, podemos crear una cuenta Heroku, obtener el cliente Heroku, y usarlo para instalar nuestro sitio web.

+ +
+

Nota: Las instrucciones indicadas abajo reflejan la forma de trabajar con Heroku en el momento de la redacción. Si Heroku cambia sus procesos de forma significativa, podrías preferir, en su lugar, revisar su documentación de instalación: Getting Started on Heroku with Django.

+
+ +

Con esto ya tienes una visión general de lo que necesitas para empezar (vea How Heroku works para tener una guía más exhaustiva).

+ +

Creando un repositorio de aplicación en Github

+ +

Heroku está estrechamente integrado con el sistema de control de versiones de código fuente git, usándolo para subir/sincronizar cualquier cambio que hagas en los sistemas activos. Esto se hace añadiendo un nuevo repositorio "remoto" heroku denominado heroku que apunta a un repositorio para tu fuente en la nube Heroku. Durante el desarrollo usas git para almacenar los cambios en tu repositorio "maestro". Cuando quieras desplegar tu sitio, sincronizas tus cambios con el repositorio Heroku.

+ +
+

Nota: Si estás acostumbrado a seguir buenas prácticas de desarrollo de software, probablemente ya estás usando git o algún otro sistema SCM. Si ya dispones de un repositorio git, podrás saltarte este paso.

+
+ +

Existen muchas formas de trabajar con git, pero una de las más sencillas es crear en primer lugar una cuenta en Github, crear allí el repositorio, y a continuación sincronizarlo localmente:

+ +
    +
  1. Visita https://github.com/ y crea una cuenta.
  2. +
  3. Una vez conectado, haz click en el enlace  + de la barra de tareas superior y selecciona New repository.
  4. +
  5. Rellena todos los campos de este formulario. Aunque no son obligatorios, es muy recomendable que los rellenes todos. +
      +
    • Introduce el nombre del nuevo repositorio (por ejemplo, django_local_library), y una descripción (por ejemplo "Sitio web de la Biblioteca Local escrita en Django").
    • +
    • Selecciona Python en la lista de selección Add .gitignore.
    • +
    • Selecciona tu licencia en la lista de selección Add license.
    • +
    • Marca Initialize this repository with a README.
    • +
    +
  6. +
  7. Pulsa Create repository.
  8. +
  9. Haz click en el botón verde "Clone or download" en la página de tu nuevo repositorio.
  10. +
  11. Copia el valor de la URL del campo de texto situado dentro de la caja de diálogo que aparece (debería decir algo como: https://github.com/<your_git_user_id>/django_local_library.git).
  12. +
+ +

Ahora que el repositorio ("repo") ha sido creado, querremos clonarlo en nuestra computadora local:

+ +
    +
  1. Instala git para tu computadora local (puedes encontrar versiones para distintas plataformas here).
  2. +
  3. Abre una ventana/terminal de comandos y clona tu repositorio usando la URL que copiaste anteriormente: +
    git clone https://github.com/<your_git_user_id>/django_local_library.git
    +
    + Esto creará el repositorio debajo del punto actual.
  4. +
  5. Navega dentro del nuevo repositorio. +
    cd django_local_library.git
    +
  6. +
+ +

El paso final es copiar en él tu aplicación y a continuación añadir los archivos a tu repositorio usando git:

+ +
    +
  1. Copia tu aplicación Django en esta carpeta (todos los archivos que estén al mismo nivel que manage.py y por debajo, no su carpeta locallibrary contenedora). 
  2. +
  3. Abre el archivo .gitignore, copia las siguientes líneas al final del mismo, y guárdalo (este archivo se utiliza para identificar los archivos que, por defecto, no deberían subirse a git). +
    # Text backup files
    +*.bak
    +
    +#Database
    +*.sqlite3
    +
  4. +
  5. Abre una ventana/terminal de comandos y utiliza el comando add para añadir todos los archivos a git. +
    git add -A
    +
    +
  6. +
  7. Utiliza el comando status para comprobar que todos los archivos que vas a añadir son correctos (quieres incluir ficheros fuentes, no binarios, archivos temporales, etc). Debería tener un aspecto similar a la lista siguiente. +
    > git status
    +On branch master
    +Your branch is up-to-date with 'origin/master'.
    +Changes to be committed:
    +  (use "git reset HEAD <file>..." to unstage)
    +
    +        modified:   .gitignore
    +        new file:   catalog/__init__.py
    +        ...
    +        new file:   catalog/migrations/0001_initial.py
    +        ...
    +        new file:   templates/registration/password_reset_form.html
    +
  8. +
  9. Si estás conforme, consolida tus archivos en el repositorio local: +
    git commit -m "First version of application moved into github"
    +
  10. +
  11. A continuación, sincroniza tu repositorio local con el sitio web Github, usando lo siguiente: +
    git push origin master
    +
  12. +
+ +

Una vez completada esta operación, deberías poder regresar a la página de Github donde creaste tu repositorio, refrescar la página, y comprobar que tu toda tu aplicación ha sido ya cargada. Puedes continuar actualizando tu repositorio según vayan cambiando los archivos, usando este ciclo add/commit/push.

+ +
+

Consejo: Este es un buen momento para hacer una copia de seguridad de tu proyecto "simple" — algunos de los cambios que vamos a ir haciendo en las siguientes secciones podrían ser útiles para el despliegue en cualquier plataforma (o para el desarrollo), pero otros no.

+ +

La mejor manera de hacer esto es usar git para gestionar tus revisiones. Con git puedes no solo volver a una versión anterior en particular, sino que puedes mantener ésta en una "rama" separada de tus cambios en producción, y seleccionar determinados cambios a trasladar entre las ramas de producción y desarrollo. Learning Git merece la pena el esfuerzo, pero queda fuera del alcance de este tema.

+ +

La forma más fácil de hacer ésto es simplemente copiar tus archivos en otra ubicación. Usa la manera que más se ajuste a tus conocimientos de git!

+
+ +

Actualizar la app para Heroku

+ +

Esta sección explica los cambios que necesitaras hacer a nuestra aplicación LocalLibrary para ponerla a funcionar en Heroku. Mientras que las instrucciones disponibles en Getting Started on Heroku with Django de Heroku asumen que también vas a utilizar el cliente Heroku para ejecutar el entorno de desarrollo local, los cambios que aquí se reflejan son compatibles con el servidor de desarrollo Django existente y las formas de funcionamiento que ya hemos aprendido.

+ +

Procfile

+ +

Crea el archivo Procfile (sin extensión) en la carpeta raíz de tu repositorio GitHub para declarar los tipos de procesos de la aplicación y los puntos de entrada. Copia en él el texto siguiente:

+ +
web: gunicorn locallibrary.wsgi --log-file -
+ +

La palabra "web:" le dice a Heroku que se trata de una web dyno y puede ser enviada a través del tráfico HTTP. El proceso a arrancar en este dyno es gunicorn, un servidor de aplicaciones web popular recomendado por Heroku. Arrancamos Gunicorn usando la información de configuración que se encuentra en el módulo locallibrary.wsgi (creado con nuestro esqueleto de aplicación: /locallibrary/wsgi.py).

+ +

Gunicorn

+ +

Gunicorn es el servidor HTTP recomendado para usar con Django en Heroku (tal como se indicaba en el Procfile anterior). Es un servidor HTTP puro-Python para aplicaciones WSGI que puede ejecutar múltiples procesos Python concurrentes dentro de un único dyno (para obtener más información, véase Deploying Python applications with Gunicorn).

+ +

Aunque no necesitaremos Gunicorn para servir nuestra aplicación LocalLibrary durante el desarrollo, lo instalaremos de manera que sean parte de nuestros requerimientos de Heroku para instalar en el servidor remoto.

+ +

Instala Gunicorn localmente usando pip en la línea de comandos (que instalamos en setting up the development environment):

+ +
pip3 install gunicorn
+
+ +

Configuración de la Base de Datos

+ +

No podemos usar la base de datos por defecto SQLite en Heroku dado que está basada-en-fichero, y sería borrada del sistema de archivos efímero cada que se reiniciara la aplicación (normalmente una vez al día, y cada vez que la aplicación o sus variables de configuración fueran modificadas).

+ +

El mecanismo de Herocu para gestionar esta situación es usar una database add-on y configurar la aplicación web utilizando información de una variable de configuración del entorno, establecida por la add-on. Existen numerosas opciones de bases de datos, pero nosotros utilizaremos el nivel hobby tier de la base de datos Heroku postgres ya que es gratuita, soportada por Django, e incorporada en nuestra nuevas apps Heroku al usar el nivel gratuito plan dyno hobby.

+ +

La información de conexión a la base de datos es proporcionada a la web dyno usando una variable de configuración denominada DATABASE_URL. En lugar de codificar esta información en Django, Heroku recomienda que los desarrolladores utilicen el paquete dj-database-url para extraer la variable de entorno DATABASE_URL y automáticamente convertirla al formato de configuración deseado por Django. Además para instalar el paquete dj-database-url necesitaremos también instalar psycopg2, ya que Django lo necesita para interactuar con la base de datos Postgres.

+ +
dj-database-url (Configuración de base de datos de  Django a partir de una variable de entorno)
+ +

Instala dj-database-url a nivel local para que se convierta en parte de nuestros requerimientos para instalar Heroku en el servidor remoto:

+ +
$ pip3 install dj-database-url
+
+ +
settings.py
+ +

Abre /locallibrary/settings.py y copia la siguiente configuración al final del archivo:

+ +
# Heroku: Update database configuration from $DATABASE_URL.
+import dj_database_url
+db_from_env = dj_database_url.config(conn_max_age=500)
+DATABASES['default'].update(db_from_env)
+ +
+

Nota:

+ + +
+ +
psycopg2 (soporte a la base de datos Python Postgres)
+ +

Django necesita psycopg2 para trabajar con las bases de datos Postgres y tú necesitarás añadir esto a los requirements.txt para que Heroku lo instale en el servidor remoto (como se expone más adelante en la sección de requerimientos).

+ +

Django utilizará la base de datos SQLite en modo local por defecto, porque la variable de entorno DATABASE_URL no está establecida en nuestro entorno local. Si quieres cambiar a Postgres completamente y usar nuestra base de datos del nivel gratuito de Heroku tanto en desarrollo como en producción, puedes hacerlo. Por ejemplo, para instalar psycopg2 y sus dependencias localmente en un sistema basado en Linux, usarías los siguientes comandos bash/terminal:

+ +
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib
+pip3 install psycopg2
+
+ +

Puedes encontrar instrucciones de instalación para el resto de plataformas en psycopg2 website.

+ +

No obstante, esto no es necesario — no necesitas tener activa PostGreSQL en el equipo local, en tanto que se lo indicas a Heroku como requerimiento, en requirements.txt (ver a continuación).

+ +

Sirviendo ficheros estáticos en producción

+ +

Durante el desarrollo utilizábamos Django y el servidor web de desarrollo de Django para servir nuestros ficheros estáticos (CSS, JavaScript, etc). En un entorno de producción normalmente se sirven los ficheros estáticos desde una red de entrega de contenidos (CDN, Content Delivery Network) o desde el servidor web.

+ +
+

Nota: Servir ficheros estáticos vía Django/aplicación web es ineficiente ya que las peticiones tienen que pasar por código adicional innecesario (Django), en vez de ser gestionados directamente por el servidor web o una CDN completamente independiente. Si bien esto no tiene relevancia en el uso local durante el desarrollo, el uso de este mecanismo en producción tiene un significativo impacto de rendimiento. 

+
+ +

Para facilitar el alojamiento de archivos estáticos de forma separada de la aplicación web Django, Django proporciona la herramienta collectstatic para recoger estos archivos para el despliegue (hay una variable de configuración que define de dónde se deben recopliar los archivos cuando se ejecuta collectstatic). Las plantillas Django hacen referencia a la localización de almacenamiento de los archivos estáticos en relación a una variable de configuración (STATIC_URL), por tanto, esto puede modificarse se los archivos estáticos son movidos a otro host/servidor.

+ +

Las variables de configuración más relevantes son:

+ + + +
settings.py
+ +

Abra /locallibrary/settings.py y copie la configuración siguiente al final del archivo. La variable BASE_DIR debería haber sido ya definida en tu fichero (la variable STATIC_URL puede haber sido ya definida dentro del archivo cuando fue creado. Puesto que no provocará ningún fallo, podrías borrar la referencias duplicadas).

+ +
# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+
+# The absolute path to the directory where collectstatic will collect static files for deployment.
+STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
+
+# The URL to use when referring to static files (where they will be served from)
+STATIC_URL = '/static/'
+
+ +

Nosotros haremos el servicio de ficheros utilizando una librería denominada WhiteNoise, que instalaremos y configuraremos en la siguiente sección.

+ +

Para más información, vea Django and Static Assets (Heroku docs).

+ +

Whitenoise

+ +

Hay muchas formas de servir ficheros estáticos en producción (ya vimos los ajustes Django relevantes en las secciones previas). Heroku recomienda usar el proyecto WhiteNoise para servir objetos estáticos directamente desde Gunicorn en producción.

+ +
+

Nota: Heroku llama automáticamente a collectstatic y prepara tus ficheros estáticos para ser usados por WhiteNoise después de que se cargue tu aplicación. Revisa la documentación WhiteNoise, en la que se explica cómo funciona y por qué la implementación es un método para servir estos ficheros relativamente eficiente.

+
+ +

Los pasos para instalar WhiteNoise para usarlo dentro del proyecto son:

+ +
WhiteNoise
+ +

Instala WhiteNoise localmente usando el siguiente comando:

+ +
$ pip3 install whitenoise
+
+ +
settings.py
+ +

Para instalar WhiteNoise en tu aplicación Django, abre /locallibrary/settings.py, busca la opción MIDDLEWARE y añade WhiteNoiseMiddleware cerca de la parte superior de la lista, justo debajo de SecurityMiddleware:

+ +
MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'whitenoise.middleware.WhiteNoiseMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ +

Opcionalmente, puedes reducir el tamaño de los ficheros estáticos al ser servidos (lo que lo hace más eficiente). Añade lo siguiente al final de /locallibrary/settings.py:

+ +
# Simplified static file serving.
+# https://warehouse.python.org/project/whitenoise/
+STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
+
+ +

Requerimientos

+ +

Los requerimientos Python de tu aplicación web deben ser almacenados en un archivo requirements.txt en la carpeta raíz de tu repositorio. Heroku los instalará cuando reconstruya tu entorno. Puedes crear este archivo utilizando pip en la línea de comandos (ejecuta los siguiente en la raíz del repositorio):

+ +
pip3 freeze > requirements.txt
+ +

Después de instalar todas las dependencias anteriores, tu archivo requirements.txt debería tener al menos estos objetos (aunque los números de versión pueden ser diferentes). Por favor, borra cualquier otra dependencia no listada abajo, a menos que la hayas añadido explícitamente para esta aplicación.

+ +
dj-database-url==0.4.1
+Django==1.10.2
+gunicorn==19.6.0
+psycopg2==2.6.2
+whitenoise==3.2.2
+
+ +
+

Asegúrate de que existe una línea psycopg2 como la que se ve arriba! Incluso aunque no lo hayas instalado localmente, deberías añadirla a requirements.txt.

+
+ +

Runtime

+ +

El archivo runtime.txt, si ha sido definido, le dice a Heroku que lenguaje de programación usar. Crea el archivo en el raíz del repositorio y añade el siguiente texto:

+ +
python-3.5.2
+ +
+

Nota: Heroku sólo soporta un número pequeño de Python runtimes. Tú puedes especificar valores de runtime de Python 3, pero en el momento de esta redacción la versión anterior será soportada como definida.

+
+ +

Guardar los cambios en Github y volver a probar.

+ +

A continuacion, guardemos nuestros cambios en Github. En el terminal (dentro de nuestro respositorio), introduce los comandos siguientes:

+ +
git add -A
+git commit -m "Added files and changes required for deployment to heroku"
+git push origin master
+ +

Antes de continuar, probemos de nuevo nuestro sitio localmente y asegurémonos de que no ha sido afectado por ninguno de los cambios anteriores. Pon en marcha el servidor web de desarrollo de la forma habitual y comprueba que el sitio aún funciona como esperas en tu navegador.

+ +
python3 manage.py runserver
+ +

Ya deberíamos estar preparados para empezar a desplegar LocalLibrary en Heroku.

+ +

Hazte con una cuenta Heroku

+ +

Para empezar a usar Heroku necesitarás en primer lugar crear una cuenta:

+ + + +

Instala el cliente

+ +

Descarga e instala el cliente Heroku siguiendo estas instructiones para Heroku.

+ +

Una vez instalado el cliente, ya podrás ejecutar comandos. Por ejemplo, para mostrar ayuda en el cliente:

+ +
heroku help
+
+ +

Crea y sube el sitio web

+ +

Para crear la app ejecutamos el comando "create" en el directorio raíz de nuestro repositorio. Esta operación crea un git remoto ("puntero hacia el repositorio remoto") denominado heroku en nuestro entorno git local.

+ +
heroku create
+ +
+

Nota: Puedes nombrar el remoto, si lo deseas, especificando un valor después de "create". Si no, obtendrás un nombre aleatorio. Este nombre es el que se utiliza en la URL por defecto.

+
+ +

Podemos a continuación "empujar" (push) nuestra aplicación hacia el respositorio Heroku como se muestra abajo. Este proceso subirá la aplicación, la empaquetará en un dyno, ejecutará collestatic, y arrancará el sitio.

+ +
git push heroku master
+ +

Si tenemos suerte, la app ya estará "corriendo" en el sitio, pero no estará funcionando correctamente ya que no hemos colocado las tablas que usa nuestra aplicación. Para hacer esto necesitamos utilizar el comando heroku run y arrancar un "one off dyno" para realizar una operación de migración. Introduce el siguiente comando en el terminal:

+ +
heroku run python manage.py migrate
+ +

Vamos a necesitar también poder añadir libros y autores, así que vamos a crear nuestro superusuario de administración, de nuevo utilizando un "one-off dyno":

+ +
heroku run python manage.py createsuperuser
+ +

Una vez llevado a cabo ésto, podremos ver el sitio. Debería funcionar, aunque no tendrá aún ningún libro. Para abrir el navegador hacia el nuevo sitio web, usa el comando:

+ +
heroku open
+ +

Crea algunos libros en el sitio de administración, y comprueba que el sitio se comporta tal y como esperas.

+ +

Gestionando addons

+ +

Puedes revisar los add-ons de tu app usando el comando heroku addons. Se listarán todos los addons, su nivel de precio y estado.

+ +
>heroku addons
+
+Add-on                                     Plan       Price  State
+─────────────────────────────────────────  ─────────  ─────  ───────
+heroku-postgresql (postgresql-flat-26536)  hobby-dev  free   created
+ └─ as DATABASE
+ +

Aquí vemos que tenemos un único add-on, la base de datos postgres SQL. Es gratuito, y fue creado automáticamente cuando se creó la aplicación. Puedes abrir una página web en la que examinar con más detalle el add-on de la base de datos (o cualquier otro add-on) utilizando el siguiente comando:

+ +
heroku addons:open heroku-postgresql
+
+ +

Otros comandos te permiten crear, destruir, subir o bajar de versión de los addons (con una sintaxis similar a la de abrir). Para más información, consulta Managing Add-ons (Heroku docs).

+ +

Estableciendo las variables de configuración

+ +

Puedes revisar las variables de configuración para el sitio con el comando heroku config. Abajo puedes comprobar que solo tenemos una variable, DATABASE_URL, usada para configurar nuestra base de datos.

+ +
>heroku config
+
+=== locallibrary Config Vars
+DATABASE_URL: postgres://uzfnbcyxidzgrl:j2jkUFDF6OGGqxkgg7Hk3ilbZI@ec2-54-243-201-144.compute-1.amazonaws.com:5432/dbftm4qgh3kda3
+ +

Si recuerdas de la sección Preparando tu sitio web para hacerlo público, tenemos que establecer variables de entorno para DJANGO_SECRET_KEY y DJANGO_DEBUG. Vamos a hacerlo ahora.

+ +
+

Nota: La clave secreta tiene que ser verdaderamente secreta! Una forma de generar una nueva clave es crear un nuevo proyecto Django (django-admin startproject nombredeproyecto) y obtener la clave generada para tí de su archivo settings.py.

+
+ +

Establecemos el valor de la variable DJANGO_SECRET_KEY con el comando config:set (como se muestra abajo). Recuerda usar tu propia clave secreta!

+ +
>heroku config:set DJANGO_SECRET_KEY=eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&=
+
+Setting DJANGO_SECRET_KEY and restarting locallibrary... done, v7
+DJANGO_SECRET_KEY: eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh
+
+ +

De forma similar, establecemos DJANGO_DEBUG:

+ +
>heroku config:set DJANGO_DEBUG=''
+
+Setting DJANGO_DEBUG and restarting locallibrary... done, v8
+ +

Si visitas ahora el sitio recibirás un error "Bad request", porque es obligatorio establecer ALLOWED_HOSTS si tienes establecido DEBUG=False (como medida de seguridad). Abre /locallibrary/settings.py y cambia el valor de ALLOWED_HOSTS para incluir la url base de tu app (por ejemplo, 'locallibrary1234.herokuapp.com') y la URL que usas normalmente en tu servidor de desarrollo local.

+ +
ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1']
+# For example:
+# ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com','127.0.0.1']
+
+ +

A continuación guarda los cambios y consolídalos en tu repo Github y en Heroku.

+ +
git add -A
+git commit -m 'Update ALLOWED_HOSTS with site and development server URL'
+git push origin master
+git push heroku master
+ +
+

Una vez completada la actualización del sitio en Heroku, introduce una URL que no exista (por ejemplo, /catalog/doesnotexist/). Antes se habría mostrado una página de depuración detallada, pero ahora deberías simplemente ver una página de "Not Found".

+
+ +

Depuración

+ +

El cliente Heroku proporciona algunas herramientas para la depuración:

+ +
heroku logs  # Show current logs
+heroku logs --tail # Show current logs and keep updating with any new results
+heroku config:set DEBUG_COLLECTSTATIC=1 # Add additional logging for collectstatic (this tool is run automatically during a build)
+heroku ps   #Display dyno status
+
+ +

Si necesitas más información de la que te proporcionan estas herramientas, tendrás que investigar en Django Logging.

+ + + +

Resumen

+ +

Has llegado al final de este tutorial sobre la instalación de apps Django en producción, así como de la serie de tutoriales sobre el trabajo con Django. Esperamos que los hayas encontrado útiles. Puedes encontrar una versión completa del código fuente en Github aquí.
+
+ El siguiente paso sería leer nuestros últimos artículos, y finalmente completar la evaluación.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Testing", "Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/development_environment/index.html b/files/es/learn/server-side/django/development_environment/index.html new file mode 100644 index 0000000000..cf47cdefa9 --- /dev/null +++ b/files/es/learn/server-side/django/development_environment/index.html @@ -0,0 +1,421 @@ +--- +title: Puesta en marcha de un entorno de desarrollo Django +slug: Learn/Server-side/Django/development_environment +tags: + - Aprendizaje + - Codificación de scripts + - Entorno de Desarrollo + - Principiante + - Python + - django + - instalación + - introducción +translation_of: Learn/Server-side/Django/development_environment +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}
+ +

Ahora que sabes para qué se utiliza Django, te enseñaremos cómo configurar y probar un entorno de desarrollo Django en Windows, Linux (Ubuntu), y Mac OS X — cualquiera que sea el sistema operativo común que estés utilizando, este artículo te dará lo que necesitas para ser capaz de empezar a desarrollar aplicaciones Django.

+ + + + + + + + + + + + +
Pre-requisitos: +

Saber como abrir un terminal / linea de comandos. Saber como instalar paquetes de software en el sistema operativo de tu computadora de desarrollo.

+
Objetivo:Tener funcionando un entorno de desarrollo Django (1.10) en tu computadora.
+ +

Visión general del entorno de desarrollo Django

+ +

Django hace muy fácil configurar tu computadora de manera que puedas empezar a desarrollar aplicaciones web. Esta sección explica qué consigues con el entorno de desarrollo y proporciona una visión general de algunas de tus opciones de puesta en marcha y configuración. El resto del artículo explica el método recomendado de instalación del entorno de desarrollo de Django en Ubuntu, Mac OS X, y Windows, y cómo puedes probarlo.

+ +

¿Qué es el entorno de desarrollo Django?

+ +

El entorno de desarrollo es una instalación de Django en tu computadora local que puedes usar para desarrollar y probar apps Django antes de desplegarlas al entorno de producción.

+ +

Las principales herramientas que el mismo Django proporciona son un conjunto de scripts de Python para crear y trabajar con proyectos Django, junto con un simple servidor web de desarrollo que puedes usar para probar de forma local (es decir en tu computadora, no en un servidor web externo) aplicaciones web Django con el explorador web de tu computadora.

+ +

Hay otras herramientas periféricas, que forman parte del entorno de desarrollo, que no cubriremos aquí. Estas incluyen cosas como un editor de textos o IDE para editar código, una herramienta de gestión del control de fuentes como Git para gestionar con seguridad las diferentes versiones de tu código. Asumimos que tienes ya un editor de textos instalado.

+ +

¿Cuáles son las opciones de puesta en marcha de Django?

+ +

Django es extremadamente flexible en términos de cómo y dónde puede instalarse y configurarse. Django puede ser:

+ + + +

Cada una de estas opciones requieren configuraciones y puesta en marcha ligeramente diferentes. Las siguientes subsecciones explican algunas de tus opciones. En el resto del artículo te mostraremos como ajustar Django en un pequeño número de sistemas operativos, y se supondrá ese ajuste a lo largo del resto del módulo.

+ +
+

Nota: La documentación oficial de Django cubre otras posibles opciones de instalación. Enlazamos a los documentos apropiados más abajo.

+
+ +

¿Qué sistemas operativos están soportados?

+ +

Las aplicaciones web Django pueden ejecutarse en casi cualquier máquina donde pueda funcionar el lenguaje de programación Python: Windows, Mac OS X, Linux/Unix, Solaris, por nombrar sólo unos pocos. Casi cualquier computadora debería tener el rendimiento necesario para ejecutar Django durante el desarrollo.

+ +

En este artículo proporcionamos instrucciones para Windows, Mac OS X, y Linux/Unix.

+ +

¿Qué versión de Python deberías usar?

+ +

Django se ejecuta por encima de Python, y puede uarse tanto con Python 2 o con Python 3 (o ambos). Cuando estés seleccionando una versión deberías tener en cuenta que:

+ + + + + +
+

Nota: Historicamente Python 2 era la única elección realista, porque muy pocas bibliotecas de terceros estaban disponibles para Python 3. La tendencia actual es que la mayoría de paquetes nuevos y populares del Python Package Index (PyPi) soporten ambas versiones de Python. Aunque todavía haya muchos paquetes que sólo están disponibles para Python 2, elegir Python 3 es actualmente una opción muy popular.

+
+ +

Te recomendamos que uses la última versión de Python 3 a menos que el sitio dependa de bibliotecas de terceros que sólo están disponibles para Python 2.

+ +

Este artículo te explicará como instalar un entorno para Python 3 (el ajuste equivalente para Python 2 sería muy similar).

+ +

¿Dónde puedo descagarme Django?

+ +

Hay tres lugares para descargar Django:

+ + + +

Este artículo te muestra como instalar Django desde PyPi, para conseguir la última versión estable.

+ +

¿Qué base de datos?

+ +

Django soporta cuatro bases de datos importantes (PostgreSQL, MySQL, Oracle y SQLite), y hay bibliotecas comunitarias que proporcionan varios niveles de soporte para otras bases de datos populares SQL y NOSQL. Te recomendamos que elijas la misma base de datos tanto para la producción como para el desarrollo (aunque Django abstrae muchas de las diferencias entre las bases usando su Object-Relational Mapper (ORM), hay todavía problemas potenciales que es mejor evitar).

+ +

Durante este artículo (y la mayoría de este módulo) usaremos la base de datos SQLite, que almacena sus datos en un fichero. SQLite está pensado para ser usado como base ligera y no puede soportar un alto nivel de concurrencia. Es sin embargo una excelente elección para aplicaciones que son principalmente de sólo lectura.

+ +
+

Nota: Django está configurado para usar SQLite por defecto cuando comienzas tu proyecto de sitio web usando las herramientas estándard (django-admin). Es una gran elección cuando estás empezando porque no requiere configuración o puesta en marcha adicional. 

+
+ +

¿Instalar Python en un entorno de sistema o virtual?

+ +

Cuando instalas Python3 obtienes un único entorno global que es compartido con todo el código Python3. Si bien puedes instalar los paquetes que te gusten en el entorno, sólo puedes instalar al mismo tiempo una versión en particular de cada paquete.

+ +
+

Nota: Las aplicaciones Python instaladas en el entorno global pueden entrar en conflicto potencialmente unas con otras (ej. si dependen de diferentes versiones del mismo paquete). 

+
+ +

Si instalas Django dentro del entorno por defecto/global sólo podrás apuntar a una sóla versión de Django en la computadora. Esto puede ser un problema si quieres crear nuevos sitios (usando la última versión de Django) pero manteniendo los sitios web que dependen de versiones más antiguas.

+ +
+ +

Como resultado, los desarrolladores experimentados de Python/Django normalmente ejecutan las aplicaciones Python dentro de entornos virtuales Python independientes. De esta forma se habilitan múltiples entornos Django diferentes en la misma computadora. !El mismo equipo de desarrollo Django recomienda que uses entornos Python virtuales!

+ +
+ +

Este módulo da por supuesto que has instalado Django en un entorno virtual, y te mostraremos cómo hacerlo más abajo.

+ +

Instalación de Python 3

+ +

Para poder usar Django tendrás que instalar Python en tu sistema operativo. Si estás usando Python 3 necesitarás la herramienta Python Package Index — pip3 — que se usa para gestionar (instalar, actualizar y eliminar) los paquetes/bibliotecas Python usados por Django y tus otras aplicaciones Python.

+ +

Esta sección explica brevemente como puedes comprobar qué versiones de Python están presentes, e instalar nuevas versiones cuando lo necesites, en Ubuntu Linux 16.04, Mac OS X, y Windows 10.

+ +
+

Nota: Dependiendo de tu plataforma, podrías también ser capaz de instalar Python/pip desde la propia aplicación de gestión de paquetes de tu sistema o vía otros mecanismos. Para la mayoría de las plataformas puedes descargar los ficheros de instalación requeridos desde https://www.python.org/downloads/ e instalarlos usando el método apropiado específico de la plataforma.

+
+ +

Ubuntu 16.04

+ +

Ubuntu Linux incluye Python 3 por defecto. Puedes confirmarlo ejecutando el siguiente comando en una terminal:

+ +
python3 -V
+ Python 3.5.2
+ +

Sin embargo la herramienta Python Package Index que necesitarás para instalar paquetes de Python 3 (incluido Django) No está disponible por defecto. Puedes instalar pip3 en un terminal bash usando:

+ +
sudo apt-get install python3-pip
+
+ +

Mac OS X

+ +

Mac OS X "El Capitan" no incluye Python 3. Puedes confirmarlo ejecutando los siguientes comandos en un terminal bash:

+ +
python3 -V
+ -bash: python3: command not found
+ +

Puedes instalar fácilmente Python 3 (junto con la herramienta pip3) desde python.org:

+ +
    +
  1. Descarga el instalador requerido: +
      +
    1. Vete a https://www.python.org/downloads/
    2. +
    3. Selecciona el botón Descarga Python 3.5.2 (el número exacto de versión menor puede ser diferente).
    4. +
    +
  2. +
  3. Localiza el fichero usando Finder, haz doble-click sobre el fichero del paquete. Pincha siguiente en las ventanas de instalación.
  4. +
+ +

Puedes confirmar ahora una instalación satisfactoria comprobando Python 3 como se muestra a continuación:

+ +
python3 -V
+ Python 3.5.20
+
+ +

Puedes igualmente comprobar que pip3 está instalado listando los paquetes disponibles:

+ +
pip3 list
+ +

Windows 10

+ +

Windows no incluye Python por defecto, pero puedes instalarlo fácilmente (junto con la herramienta pip3) desde python.org:

+ +
    +
  1. Descarga el instalador requerido: +
      +
    1. Vete a https://www.python.org/downloads/
    2. +
    3. Selecciona el botón de Descarga Python 3.6.3 (la versión menor exacta puede ser diferente).
    4. +
    +
  2. +
  3. Instala Python haciendo doble-click en el fichero descargado y pulsando siguiente en las ventanas de instalación
  4. +
+ +

Puedes verificar a continuación que Python 3 se instaló correctamente entrando el siguiente texto en una ventana de comandos:

+ +
py -3 -V
+ Python 3.6.3
+
+ +

El instalador de Windows incorpora pip3 (el gestor de paquetes de Python) por defecto. Puedes listar paquetes como se muestra a continuación:

+ +
pip3 list
+
+ +
+

Nota: El instalador debería poner en marcha todo lo que necesitas para que el comando de arriba funcione. Si por el contrario obtienes un mensaje de que Python no puede ser encontrado, puede que necesites añadirlo al path de tu sistema.

+
+ +

Uso de Django dentro de un entorno virtual de Python

+ +

Las bibliotecas que usaremos para crear nuestros entornos virtuales están en virtualenvwrapper (Linux and Mac OS X) y virtualenvwrapper-win (Windows), que utilizan a su vez la herramienta virtualenv. Las herramientas wrapper crean una interfaz consistente para la gestión de interfaces en todas las plataformas.

+ +

Instalación del software del entorno virtual

+ +

Puesta en marcha del entorno virtual en Ubuntu

+ +

Después de instalar Python y pip puedes instalar virtualenvwrapper (que incluye virtualenv) usando pip3 como se muestra.

+ +
sudo pip3 install virtualenvwrapper
+ +

A continuación añade las siguientes líneas al final del fichero de inicio de tu shell (éste es un fichero oculto llamado .bashrc que se encuentra en tu directorio de inicio del usuario). Ésto ajusta la localización de donde deberían vivir los entornos virtuales, la localización de los directorios de tus proyectos de desarrollo, y la localización del script instalado con este paquete:

+ +
export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh
+ +

A continuación volver a recargar el fichero de inicio ejecutando el siguiente comando en el terminal:

+ +
source ~/.bashrc
+ +

En este punto deberías ver un puñado de scripts empezando a ejecutarse como se muestra a continuación:

+ +
virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details
+ +

Ahora puedes crear un nuevo entorno virtual con el comando mkvirtualenv.

+ +

Puesta en marcha del entorno virtual en Mac OS X

+ +

El ajuste de virtualenvwrapper en Mac OS X es casi idéntico a como es en Ubuntu. 

+ +

Instalar virtualenvwrapper (y virtualenv incluido en el paquete) usando pip como se muestra a continuación.

+ +
sudo pip3 install virtualenvwrapper
+ +

A continuación añadir las siguientes líneas al final del fichero de inicio de tu shell. Son las mismas líneas que para Ubuntu, pero el fichero de inicio se llama de forma diferente .bash_profile y está oculto en tu directorio de inicio.

+ +
export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh
+ +

Nota: Si no puedes encontrar .bash-profile para editar en el finder, puedes también abrirlo usando nano.

+ +

Los comandos parecen algo como lo siguiente.

+ +
cd ~  # Navegar a mi directorio de inicio
+ls -la # Listar el contenido del directorio. Deberias ver .bash_profile
+nano .bash_profile # Abrir el fichero en el editor de texto nano, en el terminal
+# Avanzar hast el final del fichero, y copiar y pegar las lineas de arrriba
+# Usar Ctrl+X para salir de nano, Elegir Y para guardar el fichero.
+ +

A continuación recargar el fichero de inicio realizando la siguiente llamada en el terminal:

+ +
source ~/.bash_profile
+ +

En este punto deberías ver un puñado de scripts empezando a ejecutarse (los mismos scripts que para la instalación en Ubuntu). Deberías ser ahora capaz de crear un nuevo entorno virtual con el comado mkvirtualenv.

+ +

Puesta en marcha del entorno virtual en Windows 10

+ +

Instalar virtualenvwrapper-win es incluso más simple que poner en marcha virtualenvwrapper porque no necesitas configurar donde almacena la herramienta la información del entorno (hay un valor por defecto). Todo lo que necesitas hacer es ejecutar el siguiente comando en la consola de comandos en línea:

+ +
pip3 install virtualenvwrapper-win
+ +

Y a continuación ya puedes crear un nuevo entorno virtual con mkvirtualenv

+ +

Creación de un entorno virtual

+ +

Una vez que hayas instalado virtualenvwrapper o virtualenvwrapper-win trabajar con entornos virtuales es muy similar en todas las plataformas.

+ +

Ahora puedes crear un nuevo entorno virtual con el comando mkvirtualenv. A medida que se ejecuta este comando verás que se va poniendo en marcha el entorno (lo que verás es ligeramente específico de la plataforma). Cuando se completa el comando el nuevo entorno virtual estará activo — podrás comprobarlo porque el comienzo del prompt será el nombre del entorno entre paréntesis (como se muestra abajo).

+ +
$ mkvirtualenv my_django_environment
+
+Running virtualenv with interpreter /usr/bin/python3
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details
+(my_django_environment) ubuntu@ubuntu:~$
+
+ +

Una vez que estás dentro del entorno virutal puedes instalar Django e iniciar el desarrollo.

+ +
+

Nota: De ahora en adelante en este artículo (y por ende en el módulo) asume por favor que todos los comandos se ejecutan en un entorno virtual Python como el que acabamos de poner en marcha arriba.

+
+ +

Uso de un entorno virtual

+ +

Hay sólo otros pocos comandos útiles que deberías conocer (hay más en la documentación de la herramienta, pero éstos son los que usarás de forma habitual:

+ + + + + +

Instalación de Django

+ +

Una vez que has creado el entorno virtual, y realizado la llamada workon  para entrar en él, puedes usar pip3 para instalar Django. 

+ +
pip3 install django
+
+ +

Puedes comprobar que está instalado Django ejecutando el siguiente comando (esto sólo comprueba que Python puede encontrar el módulo Django):

+ +
# Linux/Mac OS X
+python3 -m django --version
+ 1.11.7
+
+# Windows
+py -3 -m django --version
+ 1.11.7
+
+ +
+

Nota: En Windows se lanzan scripts Python 3 añadiendo como prefijo del comando con py -3, mientras que en Linux/Mac OSX, el comando es python3.

+
+ +
+

Importante: El resto de este modulo usa, para invocar Python 3, el comando Linux (python3) . Si estás trabajando en Windows   simplemente reemplazar este prefijo con: py -3

+
+ +

Comprobación de tu instalación

+ +

La prueba de arriba funciona, pero no es muy divertida. Una comprobación más interesante es crear un esqueleto de proyecto y ver si funciona. Para hacer ésto, navega primero en tu consola de comandos/terminal a donde quieras almacenar tus aplicaciones Django. Crea una carpeta para la comprobación de tu sitio y navega a ella.

+ +
mkdir django_test
+cd django_test
+
+ +

Puedes crear a continuación un nuevo esqueleto de sitio llamado "mytestsite"  usando la herramienta django-admin como se muestra a continuación. Después de crear el sitio puedes navegar a la carpeta donde encontrarás el script principal para la gestión de proyectos, llamado manage.py.

+ +
django-admin startproject mytestsite
+cd mytestsite
+ +

Podemos arrancar el servidor web de desarrollo desde esta carpeta usando manage.py y el comando runserver, como se muestra.

+ +
$ python3 manage.py runserver 
+Performing system checks...
+
+System check identified no issues (0 silenced).
+
+You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
+Run 'python manage.py migrate' to apply them.
+
+September 19, 2016 - 23:31:14
+Django version 1.10.1, using settings 'mysite.settings'
+Starting development server at http://127.0.0.1:8000/
+Quit the server with CONTROL-C.
+
+ +
+

Nota: El comando anterior muestra el comando Linux/Mac OS X. En este punto ¡puedes ignorar las advertencias sobre "13 unapplied migration(s)"!

+
+ +

Una vez que tengas funcionando el servidor puedes ver el sitio navegando a la siguiente URL en tu explorador web local : http://127.0.0.1:8000/. Deberías ver un sitio parecido a este:

+ +

The home page of the skeleton Django app.

+ + + +

Sumario

+ +

Ahora tienes levantado y funcionando en tu computadora tu entorno de desarrollo Django .

+ +

En la sección de pruebas viste brevemente cómo crear un nuevo sitio web Django usando django-admin startproject, y hacerlo funcionar en tu explorador usando el servidor web de desarrollo (python3 manage.py runserver).

+ +

En el siguiente artículo expandimos este proceso, construyendo una aplicación web simple pero completa.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/django_assessment_blog/index.html b/files/es/learn/server-side/django/django_assessment_blog/index.html new file mode 100644 index 0000000000..cb5ac7ad88 --- /dev/null +++ b/files/es/learn/server-side/django/django_assessment_blog/index.html @@ -0,0 +1,307 @@ +--- +title: 'Evaluación: DIY Django mini blog' +slug: Learn/Server-side/Django/django_assessment_blog +translation_of: Learn/Server-side/Django/django_assessment_blog +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}
+ +

En esta evaluación usarás el conocimiento de Django que has adquirido en el módulo Framework Web Django (Python) para crear un blog muy básico.

+ + + + + + + + + + + + +
Requisitos Previos:Before attempting this assessment you should have already worked through all the articles in this module.
Objetivo:Comprender los fundamentos de Django , incluidos las configuraciones de URL , modelos, vistas, formularios y  templates.
+ +

Resumen del proyecto

+ +

Las paginas que necesitan ser mostradas, sus URLs, y otros requisitos son listados debajo: 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PaginaURLRequisitos
Home page/ and /blog/Una pagina inicial que describa el sitio
Lista de todos las publicaciones del blog/blog/blogs/ +

Lista de todos las publicaciones del blog:

+ +
    +
  • Accessible to all users from a sidebar link.
  • +
  • List sorted by post date (newest to oldest).
  • +
  • List paginated in groups of 5 articles.
  • +
  • List items display the blog title, post date, and author.
  • +
  • Blog post names are linked to blog detail pages.
  • +
  • Blogger (author names) are linked to blog author detail pages.
  • +
+
Blog autor (blogger) pagina de detalles/blog/blogger/<author-id> +

Information for a specified author (by id) and list of their blog posts:

+ +
    +
  • Accessible to all users from author links in blog posts etc.
  • +
  • Contains some biographical information about the blogger/author.
  • +
  • List sorted by post date (newest to oldest).
  • +
  • Not paginated.
  • +
  • List items display just the blog post name and post date.
  • +
  • Blog post names are linked to blog detail pages.
  • +
+
Blog post detail page/blog/<blog-id> +

Blog post details.

+ +
    +
  • Accessible to all users from blog post lists.
  • +
  • Page contains the blog post: name, author, post date, and content.
  • +
  • Comments for the blog post should be displayed at bottom.
  • +
  • Comments should be sorted in order: oldest to most recent.
  • +
  • Contains link to add comments at end for logged in users (see Comment form page)
  • +
  • Blog posts and comments need only display plain text. There is no need to support any sort of HTML markup (e.g. links, images, bold/italic, etc).
  • +
+
List of all bloggers/blog/bloggers/ +

List of bloggers on system:

+ +
    +
  • Accessible to all users from site sidebar
  • +
  • Blogger names are linked to Blog author detail pages.
  • +
+
Comment form page/blog/<blog-id>/create +

Create comment for blog post:

+ +
    +
  • Accessible to logged-in users (only) from link at bottom of blog post detail pages.
  • +
  • Displays form with description for entering comments (post date and blog is not editable).
  • +
  • After a comment has been posted, the page will redirect back to the associated blog post page.
  • +
  • Users cannot edit or delete their posts.
  • +
  • Logged out users will be directed to the login page to log in, before they can add comments. After logging in, they will be redirected back to the blog page they wanted to comment on.
  • +
  • Comment pages should include the name/link to the blogpost being commented on.
  • +
+
User authentication pages/accounts/<standard urls> +

Standard Django authentication pages for logging in, out and setting the password:

+ +
    +
  • Login/out should be accessible via sidebar links.
  • +
+
Admin site/admin/<standard urls> +

Admin site should be enabled to allow create/edit/delete of blog posts, blog authors and blog comments (this is the mechanism for bloggers to create new blog posts):

+ +
    +
  • Admin site blog posts records should display the list of associated comments inline (below each blog post).
  • +
  • Comment names in the Admin site are created by truncating the comment description to 75 characters.
  • +
  • Other types of records can use basic registration.
  • +
+
+ +

In addition you should write some basic tests to verify:

+ + + +
+

Note: There are of course many other tests you can run. Use your discretion, but we'll expect you to do at least the tests above.

+
+ +

The following section shows screenshots of a site that implements the requirements above.

+ +

Screenshots

+ +

The following screenshot provide an example of what the finished program should output.

+ +

List of all blog posts

+ +

This displays the list of all blog posts (accessible from the "All blogs" link in the sidebar). Things to note:

+ + + +

List of all blogs

+ +

List of all bloggers

+ +

This provides links to all bloggers, as linked from the "All bloggers" link in the sidebar. In this case we can see from the sidebar that no user is logged in.

+ +

List of all bloggers

+ +

Blog detail page

+ +

This shows the detail page for a particular blog.

+ +

Blog detail with add comment link

+ +

Note that the comments have a date and time, and are ordered from oldest to newest (opposite of blog ordering). At the end we have a link for accessing the form to add a new comment. If a user is not logged in we'd instead see a suggestion to log in.

+ +

Comment link when not logged in

+ +

Add comment form

+ +

This is the form to add comments. Note that we're logged in. When this succeeds we should be taken back to the associated blog post page.

+ +

Add comment form

+ +

Author bio

+ +

This displays bio information for a blogger along with their blog posts list.

+ +

Blogger detail page

+ +

Steps to complete

+ +

The following sections describe what you need to do.

+ +
    +
  1. Create a skeleton project and web application for the site (as described in Django Tutorial Part 2: Creating a skeleton website). You might use 'diyblog' for the project name and 'blog' for the application name.
  2. +
  3. Create models for the Blog posts, Comments, and any other objects needed. When thinking about your design, remember: +
      +
    • Each comment will have only one blog, but a blog may have many comments.
    • +
    • Blog posts and comments must be sorted by post date.
    • +
    • Not every user will necessarily be a blog author though any user may be a commenter.
    • +
    • Blog authors must also include bio information.
    • +
    +
  4. +
  5. Run migrations for your new models and create a superuser.
  6. +
  7. Use the admin site to create some example blog posts and blog comments.
  8. +
  9. Create views, templates, and URL configurations for blog post and blogger list pages.
  10. +
  11. Create views, templates, and URL configurations for blog post and blogger detail pages.
  12. +
  13. Create a page with a form for adding new comments (remember to make this only available to logged in users!)
  14. +
+ +

Hints and tips

+ +

This project is very similar to the LocalLibrary tutorial. You will be able to set up the skeleton, user login/logout behaviour, support for static files, views, URLs, forms, base templates and admin site configuration using almost all the same approaches.

+ +

Some general hints:

+ +
    +
  1. The index page can be implemented as a basic function view and template (just like for the locallibrary).
  2. +
  3. The list view for blog posts and bloggers, and the detail view for blog posts can be created using the generic list and detail views.
  4. +
  5. The list of blog posts for a particular author can be created by using a generic list Blog list view and filtering for blog object that match the specified author. +
      +
    • You will have to implement get_queryset(self) to do the filtering (much like in our library class LoanedBooksAllListView) and get the author information from the URL.
    • +
    • You will also need to pass the name of the author to the page in the context. To do this in a class-based view you need to implement get_context_data() (discussed below).
    • +
    +
  6. +
  7. The add comment form can be created using a function-based view (and associated model and form) or using a generic CreateView. If you use a CreateView (recommended) then: +
      +
    • You will also need to pass the name of the blog post to the comment page in the context (implement get_context_data() as discussed below).
    • +
    • The form should only display the comment "description" for user entry (date and associated blog post should not be editable). Since they won't be in the form itself, your code will need to set the comment's author in the form_valid() function so it can be saved into the model (as described here — Django docs). In that same function we set the associated blog. A possible implementation is shown below (pk is a blog id passed in from the URL/URL configuration). +
          def form_valid(self, form):
      +        """
      +        Add author and associated blog to form data before setting it as valid (so it is saved to model)
      +        """
      +        #Add logged-in user as author of comment
      +        form.instance.author = self.request.user
      +        #Associate comment with blog based on passed id
      +        form.instance.blog=get_object_or_404(Blog, pk = self.kwargs['pk'])
      +        # Call super-class form validation behaviour
      +        return super(BlogCommentCreate, self).form_valid(form)
      +
      +
    • +
    • You will need to provide a success URL to redirect to after the form validates; this should be the original blog. To do this you will need to override get_success_url() and "reverse" the URL for the original blog. You can get the required blog ID using the self.kwargs attribute, as shown in the form_valid() method above.
    • +
    +
  8. +
+ +

We briefly talked about passing a context to the template in a class-based view in the Django Tutorial Part 6: Generic list and detail views topic. To do this you need to override get_queryset() (first getting the existing context, updating it with whatever additional variables you want to pass to the template, and then returning the updated context. For example, the code fragment below shows how you can add a blogger object to the context based on their BlogAuthor id.

+ +
class SomeView(generic.ListView):
+    ...
+
+    def get_context_data(self, **kwargs):
+        # Call the base implementation first to get a context
+        context = super(SomeView, self).get_context_data(**kwargs)
+        # Get the blogger object from the "pk" URL parameter and add it to the context
+        context['blogger'] = get_object_or_404(BlogAuthor, pk = self.kwargs['pk'])
+        return context
+
+ +

Assessment

+ +

The assessment for this task is available on Github here. This assessment is primarily based on how well your application meets the requirements we listed above, though there are some parts of the assessment that check your code uses appropriate models, and that you have written at least some test code. When you're done, you can check out our the finished example which reflects a "full marks" project.

+ +

Once you've completed this module you've also finished all the MDN content for learning basic Django server-side website programming! We hope you enjoyed this module and feel you have a good grasp of the basics!

+ +

{{PreviousMenu("Learn/Server-side/Django/web_application_security", "Learn/Server-side/Django")}}

+ +

 

+ +

En este modulo

+ + diff --git a/files/es/learn/server-side/django/forms/index.html b/files/es/learn/server-side/django/forms/index.html new file mode 100644 index 0000000000..4160e537b6 --- /dev/null +++ b/files/es/learn/server-side/django/forms/index.html @@ -0,0 +1,661 @@ +--- +title: 'Tutorial de Django Parte 9: Trabajo con formularios' +slug: Learn/Server-side/Django/Forms +translation_of: Learn/Server-side/Django/Forms +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/authentication", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}
+ +

En este tutorial te mostraremos cómo trabajar con Formularios HTML en Django, y en particular, la forma más fácil de escribir formularios para crear, actualizar y borrar instancias de modelo. Como parte de esta demostración extenderemos el sitio web LocalLibrary de manera que los bibliotecarios puedan renovar libros, y crear, actualizar y borrar autores utilizando nuestros propios formularios (en vez de utilizar la aplicación de administración).

+ + + + + + + + + + + + +
Requisitos previos:Completar todos los temas de tutoriales anteriores, incluyendo Tutorial Django Parte 8: Autenticación y permisos de usuarios.
Objectivo:Comprender como escribir formularios para obtener informacion de los usuarios y actualizar la base de datos. Comprender cómo las vistas de edición basadas en clase genérica pueden simplificar enormemente la creación de formularios trabajando con un solo modelo.
+ +

Visión General

+ +

Un Formulario HTML es un conjunto de uno o más campos/widgets en una página web, que pueden ser usados para recolectar información de los usuarios para el envío a un servidor. Los formularios son un mecanismo flexible para recolectar datos de entrada porque son widgets adecuados para ingresar diferentes tipos de datos, incluyendo campos de texto, checkboxes, radio buttons, selector de fechas, etc. Los formularios son también una forma relativamente segura de compartir datos con el servidor, ya que permiten enviar información en peticiones POST con protección de falsificación de solicitud entre sitios.

+ +

Si bien nosotros aún no hemos creado ningún formulario en este tutorial todavia, ya lo hemos encontrado en el sitio de administración de Django; por ejemplo, la captura de pantalla  de abajo muestra un formulario para editar uno de nuestros modelos de Libro, compuesto de un número de listas de selección y editores de texto.

+ +

Admin Site - Book Add

+ +

Trabajar con formularios puede ser complicado! Los desarrolladores deben de escribir código HTML para el formulario, validar y adecuadamente limpiar los datos ingresados en el servidor (y posiblemente también en el browser o navegador), volver a publicar el formulario con mensajes de error para informar a los usuarios de cualquier campo invalido, manejar los datos cuando hayan sido enviados exitosamente y finalmente, responder al usuario de alguna manera, para indicar el éxito de la operación.  Django Forms  elimina mucho del trabajo de todos estos pasos, al proporcionar un marco de trabajo que le permite definir formularios y sus campos a travéz de programación y luego, utilizar estos objetos para generar el código HTML del formulario y manejar gran parte de la validación y la interacción del usuario.

+ +

En este tutorial vamos a mostrarle algunas de las formas de crear y trabajar con formularios y en particular, cómo las vistas genéricas de edición de formularios pueden significativamente reducir la cantidad del trabajo necesario para crear formularios para manejar sus modelos. En el camino iremos extendiendo nuestra aplicación LocalLibrary  por agregar un formulario para permitir a los  bibliotecarios renovar libros de la biblioteca y crearemos páginas para crear, editar o eliminar libros y autores (reproduciendo una versión básica del formulario mostrado arriba para editar libros).

+ +

Formularios HTML

+ +

Primero, una breve revisión de Formularios HTML. Considere un  simple formulario HTML, con un solo campo de texto para entrar el nombre de algun "equipo" y su etiqueta asociada:

+ +

Simple name field example in HTML form

+ +

El formulario es definido en HTML como una colección de elementos dentro de las etiquetas  <form>...</form>, conteniendo por lo menos un elemento de entrada - input de tipo enviar - type="submit".

+ +
<form action="/team_name_url/" method="post">
+    <label for="team_name">Enter name: </label>
+    <input id="team_name" type="text" name="name_field" value="Default name for team.">
+    <input type="submit" value="OK">
+</form>
+ +

Si bien acá solo tenemos un campo de texto para ingresar el nombre del equipo, un formulario puede tener cualquier número de otros elementos de entrada y sus etiquetas asociadas. El tipo del atributo del campo - type  define que clase de widget será mostrado. El nombre - name y el identificador - id del campo son usados para identificar el campo en JavaScript/CSS/HTML, mientrras que el valor - value define el valor inicial para el campo cuando este se muestra por primera vez. La etiqueta del equipo correspondiente es especificada utilizando la etiqueta - label (consulte "Enter name" arriba), con un campo  for  que contiene el valor de identificación  id de la entrada asociada input.

+ +

La entrada de envío - submit se mostrará como un botón (de forma predeterminada)  que el usuario puede presionar para cargar los datos en todos los demás elementos de entrada en el formulario al servidor (en este caso, solo el nombre del equipo - team_name). Los atributos del formulario definen el metodo -  method de HTTP usado para enviar los datos y el destino de los datos al servidor (action):

+ + + +

El rol del servidor es primero procesar el estado inicial del formulario ya sea conteniendo campos en blanco o completados previamente con valores inciales. Después de que el usuario presiona el botón de Enviar, el servidor recibirá los datos del formulario con valores del navegador web y deberá validar  la información. Si el formulario contiene datos inválidos, el servidor deberá desplegar el formulario de nuevo, esta vez con datos ingresados por el usuario en campos "válidos" y mensajes para describir el problema en los campos con valor inválidos. Una vez el servidor recibe una petición con todos los datos de formulario válidos, este puede realizar una acción apropiada (por ejemplo, guardando los datos, regresando el resultado de una búsqueda, cargando un archivo, etc.) y luego notificar al usuario.

+ +

Como puede imaginar, crear el código HTML, validar los datos retornados, redesplegar los datos ingresados con errores reportados si fuera necesario y realizar las operaciones deseadas sobre los datos válidos puede todo tomar bastante esfuerzo para "hacerlo bien". Django hace esto mucho más fácil por quitar parte del trabajo pesado y código repetitivo!

+ +

Proceso del manejo de formularios de Django

+ +

El manejo de formularios de Django utiliza las mismas técnicas que aprendimos en tutoriales anteriores (para mostrar información sobre nuestros modelos):  la vista recibe una solicitud, realiza cualquier acción requerida incluyendo leer datos de los modelos, luego generar y devolver una página HTML (de una platilla, en la que pasamos un contexto conteniendo los datos a ser desplegados).  Lo que hace las cosas más complicadas  es que el servidor también necesita poder procesar los datos proporcionados por el usuario y volver a mostrar la página si hay algún error.

+ +

A continuación se muestra un diagram de flujo del proceso de cómo Django maneja las solicitudes de formulario, comenzando con una solicitud de una página que contiene un formulario (mostrado en verde).

+ +

Updated form handling process doc.

+ +

Basado en el diagrama de anterior, las principales pasos que  hace el proceso del manejo de formularios de Django son:

+ +
    +
  1. Mostrar el formulario predeterminado la primera vez que es solicitado por el usuario. +
      +
    • El formulario puede contener campos en blanco (por ejemplo, si está creando un registro nuevo), o puede estar rellenado previamente con valores iniciales (por ejemplo, si está modificando un registro o si tiene valores iniciales predeterminados útiles).
    • +
    • El formulario se conoce como no vinculado en este punto porque no esta asociado con ningún dato ingresado por el usuario (aunque pueda tener valores iniciales).
    • +
    +
  2. +
  3. Recibir datos de una solicitud de envío y vincularlo al formulario. +
      +
    • La vinculacion de datos al formulario significa que los datos ingresados por el usuario y cualquier error están disponibles cuando necesitamos volver a desplegar el formulario. 
    • +
    +
  4. +
  5. Limpiar y validar los datos. Clean and validate the data. +
      +
    • La limpieza de los datos realiza una sanitización de la entrada (por ejemplo, remover caracteres no válidos que podrían ser usados para enviar contenido malicioso al servidor) y convertirlos en tipos consistente de Python.
    • +
    • La validación verifica que los valores sean apropiados para el campo (por ejemplo, que esten en el rango correcto de fechas, no sean demasiado cortos ni demasiado largos, etc.)
    • +
    +
  6. +
  7. Si algún dato es no válido, volver a mostrar el formulario, esta vez con cualquier valor rellenado por el usuario y los mensajes de error para los campos con problemas.
  8. +
  9. Si todos los datos son válidos, realizar las acciones requeridas (por ejemplo, guardar los datos, enviar un correo electrónico, devolver el resultado de una búsqueda, cargar un archivo, etc)
  10. +
  11. Una vez todas las acciones se hayan completado, redirijir al usuario a otra página
  12. +
+ +

Django provee una serie de herramientas y enfoques para ayudarlo con las tareas detalladas anteriormente. La más fundamental es la clase Form, la cuál simplifica la generación de formularios HTML y la limpieza y validación de datos. En la siguiente sección describimos cómo funcionan los formularios usando el ejemplo práctico de una página para permitir a los bibliotecarios renovar libros.

+ +
+

Nota:  Comprender como se usa la clase Form  lo ayudará cuando analicemos las clases de marco de formulario de más "alto nivel" de Django.

+
+ +

Renew-book form usando un Form y la funcion view

+ +

A continuación, vamos a añadir una página que permita a los bibilotecarios renovar los libros prestados. Para hacer esto crearemos un formulario que permita a los usuarios introducir una fecha. Rellenaremos el campo con un valor inicial de 3 semanas desde la fecha actual (el periodo de préstamo normal), y añadiremos alguna validación para asegurar que el bibilotecario no pueda introducir una fecha pasada o una demasiado lejana en el futuro. Cuando se haya introducido una fecha válida, la escribiremos sobre el campo BookInstance.due_back del registro actual.

+ +

El ejemplo utilizará una vista basada en funciones y una clase Form. Las próximas secciones explican como los formularios funcionan, y los cambios que necesitas realizar para continuar adelante con nuestro proyecto LocalLibrary.

+ +

Clase Form

+ +

La clase Form es el corazón del sistema de manejo de formularios de Django. Especifica los campos en el formulario, su diseño, widgets de visualización, etiquetas, valores iniciales, valores válidos y (una vez validados) los mensajes de error asociados con campos no válidos. La clase también proporciona métodos para renderizarse en plantillas usando formatos predefinidos (tablas, listas, etc.) o para obtener el valor de cualquier elemento (permitiendo el renderizado manual de grano fino).

+ +

Declarando un Form

+ +

La sintaxis de declaración para un formulario es muy similar a la de declarar un modelo, y comparte los mismos tipos de campo (y algunos parámetros similares). Esto tiene sentido porque en ambos casos debemos asegurarnos de que cada campo maneja los tipos correctos de datos, está restringido a datos válidos y tiene una descripción para la visualización / documentación.

+ +

Para crear un formulario (Form) es necesario importar la libreria forms, derivada de la clase Form, y tambien declarar los campos del formulario. A continuación se muestra una clase de formulario muy básica para nuestro formulario de renovación de libros de la biblioteca:

+ +
from django import forms
+
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+ +

Campos del Form

+ +

En este caso, tenemos un único DateField para ingresar la fecha de renovación que se mostrará en HTML con un valor en blanco, la etiqueta predeterminada "Fecha de renovación:" y algún texto de uso útil: "Ingrese una fecha entre ahora y 4 semanas (valor predeterminado 3 semanas)." Como no se especifica ninguno de los otros argumentos opcionales, el campo aceptará fechas utilizando los input_formats: AAAA-MM-DD (2016-11-06), MM / DD / AAAA (26/02/2016), MM / DD / AA ( 25/10/16), y se representará con el widget predeterminado: DateInput.

+ +

Hay muchos otros tipos de campos de formulario, que reconocerá en gran medida por su similitud con las clases de campo de modelo equivalentes: BooleanField, CharField, ChoiceField, TypedChoiceField, DateField, DateTimeField, DecimalField, DurationField, EmailField, FileField, FilePathField, FloatField, ImageField, IntegerField, GenericIPAddressField, MultipleChoiceField, TypedMultipleChoiceField, NullBooleanField, RegexField, SlugField, TimeField, URLField, UUIDField, ComboField, MultiValueField, SplitDateTimeField, ModelMultipleChoiceField, ModelChoiceField​​​​.

+ +

Los argumentos que son comunes a la mayoría de los campos se enumeran a continuación (estos tienen valores predeterminados sensibles):

+ + + +

Validación

+ +

Django proporciona numerosos lugares donde puede validar sus datos. La forma más fácil de validar un solo campo es anular el método clean_<fieldname>() para el campo que desea verificar. Entonces, por ejemplo, podemos validar lo ingresado renewal_date los valores son entre ahora y 4 semanas mediante la implementación clean_renewal_date() como se muestra abajo.

+ +
from django import forms
+
+from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext_lazy as _
+import datetime #for checking renewal date range.
+
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+    def clean_renewal_date(self):
+        data = self.cleaned_data['renewal_date']
+
+        #Check date is not in past.
+        if data < datetime.date.today():
+            raise ValidationError(_('Invalid date - renewal in past'))
+
+        #Check date is in range librarian allowed to change (+4 weeks).
+        if data > datetime.date.today() + datetime.timedelta(weeks=4):
+            raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+        # Remember to always return the cleaned data.
+        return data
+ +

Hay dos cosas importantes a tener en cuenta. El primero es que obtenemos nuestros datos usando self.cleaned_data['renewal_date'] y que devolvemos estos datos si los cambiamos o no al final de la función. Este paso nos permite "limpiar" y desinfectar los datos de entrada potencialmente insegura utilizando los validadores predeterminados, y convertirlos al tipo estándar correcto para los datos (en este caso, un objeto Python  datetime.datetime).

+ +

El segundo punto es que si un valor cae fuera de nuestro rango, elevamos un ValidationError, especificando el texto de error que queremos mostrar en el formulario si se ingresa un valor no válido. El ejemplo anterior también envuelve este texto en uno de las funciones de traduccion de Django ugettext_lazy() (importado como _()), lo cual es una buena práctica si desea traducir su sitio más tarde.

+ +
+

Nota: Existen muchos otros métodos y ejemplos para validar formularios en Validacion de Formularios  y campos (Django docs). Por ejemplo, en los casos en que tiene varios campos que dependen unos de otros, puede anular la función Form.clean() function y colocar un ValidationError.

+
+ +

¡Eso es todo lo que necesitamos para el formulario en este ejemplo!

+ +

Copia el Formulario

+ +

Crea y abre el archivo locallibrary/catalog/forms.py y copie el listado completo del código del bloque anterior en él.

+ +

Configuracion del URL

+ +

Antes de crear nuestra vista, agreguemos una configuración de URL para la página de renovar libros. Copie la siguiente configuración en la parte inferior de  locallibrary/catalog/urls.py.

+ +
urlpatterns += [
+    url(r'^book/(?P<pk>[-\w]+)/renew/$', views.renew_book_librarian, name='renew-book-librarian'),
+]
+ +

La configuración de URL redirigirá las URL con el formato  /catalog/book/<bookinstance id>/renew/ a la función llamada renew_book_librarian() en views.py, y envia el id de BookInstance como parametro llamado pk.

+ +
+

Nota: Podemos nombrar nuestros datos de URL capturados "pk" como queramos, porque tenemos un control completo sobre la función de vista (no estamos usando una clase de vista de detalles genérica que espere parámetros con un nombre determinado). sin embargo pk, abreviatura de "primary key", es una convención razonable de usar!

+
+ +

View

+ +

Como se discutió en el proceso de manejo de formularios de Django arriba, la vista debe presentar el formulario predeterminado cuando se llama por primera vez y luego volver a representarlo con mensajes de error si los datos no son válidos, o procesar los datos y redirigirlos a una nueva página si los datos son válidos. Para realizar estas diferentes acciones, la vista debe poder saber si se está llamando por primera vez para presentar el formulario predeterminado, o una vez posterior para validar los datos.

+ +

Para formularios que usan una solicitud POST  para enviar información al servidor, el patrón más común es que la vista pruebe con el tipo de solicitud  POST  (if request.method == 'POST':) para identificar las solicitudes de validación de formularios y GET (usando una condición else ) para identificar la solicitud de creación de formulario inicial. Si desea enviar sus datos utilizando una solicitud GET  entonces, un enfoque típico para identificar si esta es la primera invocación de vista o posterior es leer los datos del formulario (por ejemplo, leer un valor oculto en el formulario).

+ +

El proceso de renovacion de un libro escribira cambios en nuestra base de datos , entonces por convencion usaremos una peticion de tipo POST. El siguiente fragmento de código muestra el patrón (muy estándar) para este tipo de vista de funciones. 

+ +
from django.shortcuts import get_object_or_404
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+import datetime
+
+from .forms import RenewBookForm
+
+def renew_book_librarian(request, pk):
+    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+ +

Primero importamos nuestro formulario (RenewBookForm) y una serie de otros objetos / métodos útiles utilizados en el cuerpo de la función de vista:

+ + + +

En la vista, primero usamos el argumento pk argument en  get_object_or_404() para obtener el actual BookInstance (si esto no existe, la vista se cerrará inmediatamente y la página mostrará un error "no encontrado"). Si no se trata de una solicitud POST (manejada por la cláusula else), creamos el formulario predeterminado que pasa un valor inicial (initial) para el campo renewal_date (como se muestra en negrita a continuación, esto es 3 semanas desde la fecha actual)..

+ +
    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a GET (or any other method) create the default form
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+ +

Después de crear el formulario, llamamos render() para crear la página HTML, especificando la plantilla y un contexto que contiene nuestro formulario. En este caso, el contexto también contiene nuestro BookInstance, que usaremos en la plantilla para proporcionar información sobre el libro que estamos renovando.

+ +

Sin embargo, si esto es una solicitud POST, entonces crearemos nuestro objeto form y llenarlo con datos de la solicitud. Este proceso se llama "enlace" (binding) y nos permite validar el formulario. Luego verificamos si el formulario es válido, que ejecuta todo el código de validación en todos los campos, incluido el código genérico para verificar que nuestro campo de fecha sea realmente una fecha válida y nuestra funcion del formulario clean_renewal_date() chequea la fecha que tenga un rango correcto. 

+ +
    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+ +

Si el formulario no es válido llamamos render() de nuevo, pero esta vez el valor del formulario pasado en el contexto incluirá mensajes de error.

+ +

Si el formulario es válido, entonces podemos comenzar a usar los datos, accediendo a ellos a través del atributo form.cleaned_data (ejemplo data = form.cleaned_data['renewal_date']). Aquí solo guardamos los datos en el valor due_back asociado al objeto BookInstance.

+ +
+

Importante: Si bien también puede acceder a los datos del formulario directamente a través de la solicitud (por ejemplo request.POST['renewal_date'] o request.GET['renewal_date'] (si se esta usando una solicitud GET) esto NO es recomendable. Los datos limpios se desinfectan, validan y convierten en tipos compatibles con Python.

+
+ +

El paso final en la parte de manejo de formularios de la vista es redirigir a otra página, generalmente una página de "éxito". En este caso usamos HttpResponseRedirect y reverse() para redirigir a la vista llamada  'all-borrowed'(esto fue creado como el "desafío" en Django Tutorial Part 8: User authentication and permissions).Si no creó esa página, considere redirigir a la página de inicio en la URL '/').

+ +

Eso es todo lo necesario para el manejo del formulario en sí, pero aún debemos restringir el acceso a la vista a los bibliotecarios. Probablemente deberíamos crear un nuevo permiso en BookInstance ("can_renew"),pero para simplificar las cosas aquí solo usamos la funcion decorator @permission_required  con nuestro existente permiso can_mark_returned.

+ +

La vista final es, por lo tanto, como se muestra a continuación. Copie esto en la parte inferior de locallibrary/catalog/views.py.

+ +
from django.contrib.auth.decorators import permission_required
+
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponseRedirect
+from django.url import reverse
+import datetime
+
+from .forms import RenewBookForm
+
+@permission_required('catalog.can_mark_returned')
+def renew_book_librarian(request, pk):
+    """
+    View function for renewing a specific BookInstance by librarian
+    """
+    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+
+ +

La plantilla

+ +

Crea la plantilla html referenciada en la vista dentro del directorio (/catalog/templates/catalog/book_renew_librarian.html) y copia el codigo a continuacion dentro del archivo que creaste:

+ +
{% extends "base_generic.html" %}
+{% block content %}
+
+    <h1>Renew: \{{bookinst.book.title}}</h1>
+    <p>Borrower: \{{bookinst.borrower}}</p>
+    <p{% if bookinst.is_overdue %} class="text-danger"{% endif %}>Due date: \{{bookinst.due_back}}</p>
+
+    <form action="" method="post">
+        {% csrf_token %}
+        <table>
+        \{{ form }}
+        </table>
+        <input type="submit" value="Submit" />
+    </form>
+
+{% endblock %}
+ +

La mayor parte de esto será completamente familiar de los tutoriales anteriores. Extendemos la plantilla base y luego redefinimos el bloque de contenido. Podemos hacer referencia\{{bookinst}} (y sus variables) porque se pasó al objeto de contexto en la funci'on render(),y los usamos para colocar el título del libro, el prestatario y la fecha de vencimiento original.

+ +

El código del formulario es relativamente simple. Primero declaramos las etiquetas del form,especificando dónde se debe enviar el formulario (action) y el  metodo para enviar los datos (en este caso, una "POST HTTP"), si recuerda el HTML Forms resumen en la parte superior de la página, un espacio vacío actioncomo se muestra, significa que los datos del formulario se volverán a publicar en la URL actual de la página (¡que es lo que queremos!). Dentro de las etiquetas definimos la enntrada (input) submit, que un usuario puede presionar para enviar los datos. Esto {% csrf_token %} es agregado justo dentro de las etiquetas de formulario es parte de la protección de falsificación entre sitios de Django.

+ +
+

Nota: Agregue el {% csrf_token%} a cada plantilla de Django que cree que use POST para enviar datos. Esto reducirá la posibilidad de que usuarios malintencionados secuestran formularios.

+
+ +

Todo lo que queda es la variable de la plantilla  \{{form}}, que pasamos a la plantilla en el diccionario de contexto. Quizás, como era de esperar, cuando se usa como se muestra, proporciona la representación predeterminada de todos los campos del formulario, incluidas sus etiquetas, widgets y texto de ayuda; la representación es la que se muestra a continuación:

+ +
<tr>
+  <th><label for="id_renewal_date">Renewal date:</label></th>
+  <td>
+    <input id="id_renewal_date" name="renewal_date" type="text" value="2016-11-08" required />
+    <br />
+    <span class="helptext">Enter date between now and 4 weeks (default 3 weeks).</span>
+  </td>
+</tr>
+
+ +
+

Nota: Quizás no sea obvio porque solo tenemos un campo, pero de forma predeterminada cada campo se define en su propia fila de tabla (razón por la cual la variable está dentro de la etiqueta table  arriba).​​​​Esta misma representación (rendering) se proporciona si hace referencia a la variable de plantilla \{{ form.as_table }}.

+
+ +

Si tuviera que ingresar una fecha no válida, también obtendría una lista de los errores que se muestran en la página (en negrita a continuación).

+ +
<tr>
+  <th><label for="id_renewal_date">Renewal date:</label></th>
+   <td>
+      <ul class="errorlist">
+        <li>Invalid date - renewal in past</li>
+      </ul>
+      <input id="id_renewal_date" name="renewal_date" type="text" value="2015-11-08" required />
+      <br />
+      <span class="helptext">Enter date between now and 4 weeks (default 3 weeks).</span>
+    </td>
+</tr>
+ +

Otras formas de usar variable de la plantilla de formulario

+ +

Usando \{{form}} como se muestra arriba, cada campo se representa como una fila de la tabla. También puede representar cada campo como un elemento de la lista (usando \{{form.as_ul}} ) o como un parrafo (usando \{{form.as_p}}).

+ +

Lo que es aún más genial es que puede tener un control completo sobre la representación de cada parte del formulario, indexando sus propiedades mediante la notación de puntos. Entonces, por ejemplo, podemos acceder a una serie de elementos separados de los campos de renewal_date-

+ + + +

Para obtener más ejemplos de cómo reproducir manualmente los formularios en plantillas y recorrer dinámicamente los campos de la plantilla, vea Working with forms > Rendering fields manually (Django docs).

+ +

Probando la página

+ +

Si aceptó el "desafío" en Django Tutorial Part 8: User authentication and permissions tendrá una lista de todos los libros prestados en la biblioteca, que solo es visible para el personal de la biblioteca. Podemos agregar un enlace a nuestra página de renovación al lado de cada artículo usando el código de plantilla a continuación.

+ +
{% if perms.catalog.can_mark_returned %}- <a href="{% url 'renew-book-librarian' bookinst.id %}">Renew</a>  {% endif %}
+ +
+

Nota: Recuerde que su inicio de sesión de prueba deberá tener el permiso "catalog.can_mark_returned" para acceder a la página de renovar el libro (quizás use su cuenta de superusuario).

+
+ +

Alternativamente, puede construir manualmente una URL de prueba como esta — http://127.0.0.1:8000/catalog/book/<bookinstance_id>/renew/ (se puede obtener un ID de instancia de libro válido navegando a la página de detalles de un libro en su biblioteca y copiando el campo id).

+ +

Como se ve?

+ +

Si tiene éxito, el formulario predeterminado se verá así:

+ +

+ +

El formulario con un valor no válido ingresado se verá así:

+ +

+ +

La lista de todos los libros con enlaces renovados se verá así:

+ +

+ +

ModelForms

+ +

Crear una clase Form utilizando el enfoque descrito anteriormente es muy flexible, lo que le permite crear cualquier tipo de página de formulario que desee y asociarla con cualquier modelo o modelos.

+ +

Sin embargo, si solo necesita un formulario para asignar los campos de un solo modelo, entonces su modelo ya definirá la mayor parte de la información que necesita en su formulario: campos, etiquetas, texto de ayuda, etc. En lugar de recrear las definiciones de modelo en su formulario , es más fácil usar una clase auxiliar ModelForm para crear el formulario a partir de su modelo. El  ModelForm puede usarse dentro de sus vistas exactamente de la misma manera que un ordinario Form.

+ +

Un ModelForm que contiene el mismo campo que nuestro original RenewBookFormse muestra a continuación. Todo lo que necesita hacer para crear el formulario es agregar class Meta with the associated model (BookInstance) y una lista de los campos del  modelo fieldspara incluir en el formulario (puede incluir todos los campos usando fields = '__all__', o puedes usar exclude (en vez de fields) para especificar los campos que no se incluirán del modelo).

+ +
from django.forms import ModelForm
+from .models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+    class Meta:
+        model = BookInstance
+        fields = ['due_back',]
+
+ +
+

Nota: Esto podría no parece mucho más simple que simplemente usar un Form(y no es en este caso, porque solo tenemos un campo). Sin embargo, si tiene muchos campos, puede reducir la cantidad de código de manera bastante significativa.

+
+ +

El resto de la información proviene de las definiciones de campo del modelo (por ejemplo, etiquetas, widgets, texto de ayuda, mensajes de error). Si estos no son del todo correctos, entonces podemos anularlos en nuestro class Meta, especificando un diccionario que contiene el campo a cambiar y su nuevo valor. Por ejemplo, en este formulario podríamos querer una etiqueta para nuestro campo de "Fecha de renovación" (en lugar del valor predeterminado basado en el nombre del campo: Fecha de vencimiento), y también queremos que nuestro texto de ayuda sea específico para este caso de uso. El Meta a continuación le muestra cómo anular estos campos, y puede configurar de manera similar widgets y error_messages si los valores predeterminados no son suficientes.

+ +
class Meta:
+    model = BookInstance
+    fields = ['due_back',]
+    labels = { 'due_back': _('Renewal date'), }
+    help_texts = { 'due_back': _('Enter a date between now and 4 weeks (default 3).'), } 
+
+ +

Para agregar validación, puede usar el mismo enfoque que para un normal Form — define una función llamada clean_field_name() y coloca (raise)  ValidationError excepciones para valores no válidos. La única diferencia con respecto a nuestro formulario original es que el campo modelo se llama due_back y no "renewal_date".

+ +
from django.forms import ModelForm
+from .models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+    def clean_due_back(self):
+       data = self.cleaned_data['due_back']
+
+       #Check date is not in past.
+       if data < datetime.date.today():
+           raise ValidationError(_('Invalid date - renewal in past'))
+
+       #Check date is in range librarian allowed to change (+4 weeks)
+       if data > datetime.date.today() + datetime.timedelta(weeks=4):
+           raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+       # Remember to always return the cleaned data.
+       return data
+
+    class Meta:
+        model = BookInstance
+        fields = ['due_back',]
+        labels = { 'due_back': _('Renewal date'), }
+        help_texts = { 'due_back': _('Enter a date between now and 4 weeks (default 3).'), }
+
+ +

La clase RenewBookModelForm a continuación es ahora funcionalmente equivalente a nuestro original RenewBookForm. Puede importarlo y usarlo donde quiera que lo use actualmente RenewBookForm.

+ +

Vistas de edición genéricas

+ +

El algoritmo de manejo de formularios que utilizamos en nuestro ejemplo de vista de funciones anterior representa un patrón extremadamente común en las vistas de edición de formularios. Django extrae gran parte de esta "plantilla" para ti, para crear vistas de edición genéricas ( generic editing views ) para crear, editar y eliminar vistas basadas en modelos. No solo manejan el comportamiento de "vista", sino que crean automáticamente la clase de formulario (un ModelForm) para tu modelo.

+ +
+

Nota: Además de las vistas de edición descritas aquí, también hay una clase FormView , que se encuentra en algún lugar entre nuestra vista de función y las otras vistas genéricas en términos de "flexibilidad" frente a "esfuerzo de codificación". Usando FormView tu necesitas crear el Form, pero no tiene que implementar todo el patrón estándar de manejo de formularios. En su lugar, solo tiene que proporcionar una implementación de la función que se llamará una vez que se sepa que el envío es válido.

+
+ +

En esta sección, vamos a usar vistas de edición genéricas para crear páginas para agregar funcionalidad para crear, editar y eliminar registros de Author de nuestra libreria — Proporcionar efectivamente una reimplementación básica de partes del sitio de administración (esto podría ser útil si necesita ofrecer la funcionalidad de administrador de una manera más flexible que puede proporcionar el sitio de administrador).

+ +

Views

+ +

Abre el archivo de vistas (locallibrary/catalog/views.py) y agregue el siguiente bloque de código al final:

+ +
from django.views.generic.edit import CreateView, UpdateView, DeleteView
+from django.urls import reverse_lazy
+from .models import Author
+
+class AuthorCreate(CreateView):
+    model = Author
+    fields = '__all__'
+    initial={'date_of_death':'05/01/2018',}
+
+class AuthorUpdate(UpdateView):
+    model = Author
+    fields = ['first_name','last_name','date_of_birth','date_of_death']
+
+class AuthorDelete(DeleteView):
+    model = Author
+    success_url = reverse_lazy('authors')
+ +

Como puede ver, para crear las vistas de las que necesita derivar CreateView, UpdateView, y DeleteView (respectivamente) y luego definir el modelo asociado.

+ +

Para los casos de "crear" y "actualizar", también debe especificar los campos para mostrar en el formulario (utilizando la misma sintaxis que para ModelForm). En este caso, mostramos la sintaxis para mostrar "todos" los campos y cómo puede enumerarlos individualmente. También puede especificar valores iniciales para cada uno de los campos utilizando un diccionario de pares nombre_campo / valor (aquí establecemos arbitrariamente la fecha de fallecimiento para fines de demostración; ¡es posible que desee eliminar eso!). Por defecto, estas vistas redirigirán en caso de éxito a una página que muestre el elemento del modelo recién creado / editado, que en nuestro caso será la vista detallada del autor que creamos en un tutorial anterior. Puede especificar una ubicación alternativa de redireccionamiento declarando explícitamente el parámetro success_url (como hecho en la clase AuthorDelete ).

+ +

La clase AuthorDelete no necesita mostrar ninguno de los campos, por lo que no es necesario especificarlos. Sin embargo, debe especificar el success_url, porque no hay un valor predeterminado obvio para que Django lo use. En este caso usamos la función reverse_lazy() para redirigir a nuestra lista de autores después de que un autor ha sido eliminado — reverse_lazy() is a lazily executed version of reverse(), se usa aquí porque estamos proporcionando una URL a un atributo de vista basado en clases.

+ +

Templates - Plantillas

+ +

Las vistas "create" y "update" utilizan la misma plantilla de forma predeterminada, que se nombrará después de su model: model_name_form.html (puedes cambiar el sufijo a algo diferente a _form usando el campo  template_name_suffixen tu vista, ejemplo: template_name_suffix = '_other_suffix')

+ +

Crea la siguiente plantilla locallibrary/catalog/templates/catalog/author_form.html  y copia el siguiente texto:

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+<form action="" method="post">
+    {% csrf_token %}
+    <table>
+    \{{ form.as_table }}
+    </table>
+    <input type="submit" value="Submit" />
+
+</form>
+{% endblock %}
+ +

Esto es similar a nuestros formularios anteriores y representa los campos usando una tabla. Tenga en cuenta también cómo declaramos nuevamente{% csrf_token %} para garantizar que nuestros formularios sean resistentes a los ataques CSRF.

+ +

La vista "delete" espera encontrar una plantilla con el formato model_name_confirm_delete.html (de nuevo, puedes cambiar el sufijo usando template_name_suffix en tu vista). Crea la siguiente plantilla locallibrary/catalog/templates/catalog/author_confirm_delete.html y copia en el texto a continuación.

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+
+<h1>Delete Author</h1>
+
+<p>Are you sure you want to delete the author: \{{ author }}?</p>
+
+<form action="" method="POST">
+  {% csrf_token %}
+  <input type="submit" action="" value="Yes, delete." />
+</form>
+
+{% endblock %}
+
+ +

Configuración de URL

+ +

Abra el archivo de configuración de URL (locallibrary/catalog/urls.py) y agregue la siguiente configuración al final del archivo:

+ +
urlpatterns += [
+    url(r'^author/create/$', views.AuthorCreate.as_view(), name='author_create'),
+    url(r'^author/(?P<pk>\d+)/update/$', views.AuthorUpdate.as_view(), name='author_update'),
+    url(r'^author/(?P<pk>\d+)/delete/$', views.AuthorDelete.as_view(), name='author_delete'),
+]
+ +

¡No hay nada particularmente nuevo aquí! Puede ver que las vistas son clases y, por lo tanto, deben llamarse a través de .as_view(),y deberías poder reconocer los patrones de URL en cada caso. Debemos usar pk como el nombre de nuestro valor de clave principal (primary key) capturado, ya que este es el nombre del parámetro esperado por las clases de vista.

+ +

Las páginas de crear, actualiza y eliminar autor ahora estan listas para probar (no nos molestaremos en engancharlas en la barra lateral del sitio en este caso, aunque puede hacerlo si lo desea).

+ +
+

Nota:¡Los usuarios observadores habrán notado que no hicimos nada para evitar que usuarios no autorizados accedan a las páginas! Lo dejamos como un ejercicio para usted (pista: puede usar el PermissionRequiredMixin y cree un nuevo permiso o reutilice nuestro permiso can_mark_returned ).

+
+ +

Probando la página

+ +

Primero inicie sesión en el sitio con una cuenta que tenga los permisos que haya decidido que se necesitan para acceder a las páginas de edición del autor.

+ +

Luego navegue a la página de creación del autor: http://127.0.0.1:8000/catalog/author/create/, que debería verse como la captura de pantalla a continuación.

+ +

Form Example: Create Author

+ +

Ingrese los valores para los campos y luego presione Submit para guardar el registro del autor. Ahora debería ser llevado a una vista detallada para su nuevo autor, con una URL de algo como http://127.0.0.1:8000/catalog/author/10.

+ +

Puede probar la edición de registros agregando /update/ hasta el final de la vista detallada URL (e.g. http://127.0.0.1:8000/catalog/author/10/update/) — no mostramos una captura de pantalla, porque se parece a la página "create".

+ +

Por último, podemos eliminar el autor, agregando eliminar (delete) al final de la vista detallada del autor URL (ejemplo. http://127.0.0.1:8000/catalog/author/10/delete/). Django debería mostrar la página de eliminación que se muestra a continuación. pulse Yes, delete. para eliminar el registro y ser llevado a la lista de todos los autores.

+ +

+ +

Retarte a ti mismo

+ +

Crea algunos formularios para crear, editar y eliminar registros de Book.Puede usar exactamente la misma estructura de Authors. Si tu plantilla  book_form.html es solo una versión renombrada de la copia de la plantilla   author_form.html, entonces la nueva página "crear libro" se verá como la captura de pantalla a continuación:

+ +

+ + + +

Resumen

+ +

¡Crear y manejar formularios puede ser un proceso complicado! Django lo hace mucho más fácil al proporcionar mecanismos programáticos para declarar, representar y validar formularios. Además, Django proporciona vistas genéricas de edición de formularios que pueden hacer casi todo el trabajo para definir páginas que pueden crear, editar y eliminar registros asociados con una sola instancia de modelo.

+ +

Hay mucho más que se puede hacer con los formularios (consulte nuestra lista Vea también a continuación), pero ahora debe comprender cómo agregar formularios básicos y código de manejo de formularios a sus propios sitios web.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/authentication", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/generic_views/index.html b/files/es/learn/server-side/django/generic_views/index.html new file mode 100644 index 0000000000..7eb6830a87 --- /dev/null +++ b/files/es/learn/server-side/django/generic_views/index.html @@ -0,0 +1,640 @@ +--- +title: 'Tutorial de Django Parte 6: Listas genéricas y vistas de detalle' +slug: Learn/Server-side/Django/Generic_views +tags: + - Aprender + - Principiante + - Tutorial + - django + - plantillas django + - vistas django +translation_of: Learn/Server-side/Django/Generic_views +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}
+ +

Este tutorial extiende nuestro sitio web de la BibliotecaLocal, añadiendo páginas de listas y detalles de libros y autores. Aquí aprenderemos sobre vistas genéricas basadas en clases, y mostraremos cómo éstas pueden reducir la cantidad de código que tienes que escribir para casos de uso común. También entraremos en el manejo de URL en gran detalle, mostrando cómo realizar un emparejamiento de patrones básico.

+ + + + + + + + + + + + +
Requisitos previos: +

Completa todos los tópicos anteriores del tutorial, incluyendo Tutorial de Django Parte 5: Creación de tu página de inicio.

+
Objetivo: +

Entender dónde y cómo usar las vistas genéricas basadas en clases, y cómo extraer patrones desde las URLs y enviar la información a las vistas.

+
+ +

Visión General

+ +

En este tutorial vamos a completar la primera versión del sitio web BibliotecaLocal añadiendo páginas de lista y detalle para libros y autores (o para ser más precisos, te mostraremos cómo implementar las páginas de libros, ¡y te dejaremos crear las páginas de autores por tí mismo!)

+ +

El proceso es similar al de creación de la página índice, que mostramos en el tutorial anterior. Aquí también necesitaremos crear mapeos URL, vistas y plantillas. La principal diferencia es que para las páginas de detalle tendremos el reto adicional de extraer información desde patrones en las URLs y pasarla a la vista. Para estas páginas vamos a mostrar un tipo de vista completamente diferente: vistas genéricas de lista y detalle basadas en clases. Estas pueden reducir significativamente la cantidad de código requerido para las vistas, haciéndolas más fáciles de escribir y mantener.

+ +

La parte final del tutorial mostrará cómo paginar tu información al usar vistas de lista genéricas basadas en clases.

+ +

Página de lista de libros

+ +

La página de lista de libros desplegará una lista con todos los registros de libros disponibles en la página, a la cual se accede usando la URL:  catalog/books/. La página desplegará un título y un autor para cada registro, siendo el título un hipervículo a la página de detalle de libro relacionada. La página tendrá la misma estructura y navegación que todas las demás páginas en el sitio, y por tanto podemos extender la plantilla base (base_generic.html) que creamos en el tutorial anterior.

+ +

Mapeo URL

+ +

Abre /catalog/urls.py y copia allí la línea que se muestra abajo en negrita. De manera muy similar al mapeo de nuestro índice, esta función url() define una expresión regular (RE) para comparala con la URL (r'^books/$'), una función de vista que será llamada si la URL coincide (views.BookListView.as_view()) y un nombre para este mapeo en particular.

+ +
urlpatterns = [
+    url(r'^$', views.index, name='index'),
+    url(r'^books/$', views.BookListView.as_view(), name='books'),
+]
+ +

Esta expresión regular coincide con URLs iguales a books/ (^ es un marcador de inicio de cadena y $ es un marcador de fin de cadena). Como se discutió en el tutorial anterior, la URL debió previamente haber coincidido con /catalog, de modo que la vista será llamada en realidad para la URL: /catalog/books/.

+ +

La función de vista tiene un formato diferente al anterior -- eso es porque esta vista será en realidad implementada como una clase. Heredaremos desde una función de vista genérica existente que ya hace la mayoría de lo que queremos que esta función de vista haga, en lugar de escribir la nuestra propia desde el inicio.

+ +

Para las vistas basadas en clases de Django, accedemos a una función de vista apropiada llamando al método de clase as_view(). Esto hace todo el trabajo de crear una instancia de la clase, y asegurarse de que los métodos controladores correctos sean llamados para las solicitudes HTTP entrantes.

+ +

Vista (basada en clases)

+ +

Podríamos fácilmente escribir la vista de lista de libros como una función regular (tal como nuestra vista de índice anterior), la cual consultaría a la base de datos por todos los libros, y luego llamar a render() para pasar dicha lista a una plantilla específica. Sin embargo, en lugar de eso usaremos una vista de lista genérica basada en clases (ListView) -- una clase que hereda desde una vista existente. Debido a que la vista genérica ya implementa la mayoría de la funcionalidad que necesitamos, y sigue la práctica adecuada de Django, seremos capaces de crear una vista de lista más robusta con menos código, menos repetición, y por último menos mantenimiento.

+ +

Abre catalog/views.py, y copia el siguiente código al final del archivo:

+ +
from django.views import generic
+
+class BookListView(generic.ListView):
+    model = Book
+ +

¡Eso es todo! La vista genérica consultará a la base de datos para obtener todos los registros del modelo especificado (Book) y renderizará una plantilla ubicada en /locallibrary/catalog/templates/catalog/book_list.html (que crearemos más abajo). Dentro de la plantilla puedes acceder a la lista de libros mediante la variable de plantilla llamada object_list O book_list (esto es, genéricamente, "nombre_del_modelo_list").

+ +
+

Nota: Esta ruta complicada para la ubicación de la plantilla no es un error de digitación -- las vistas genéricas buscan plantillas en /application_name/the_model_name_list.html (catalog/book_list.html en este caso) dentro del directorio de la aplicación /application_name/templates/ (/catalog/templates/).

+
+ +

Puedes añadir atributos para cambiar el comportamiento por defecto de arriba. Por ejemplo, puedes especificar otro archivo de plantilla si necesitas tener múltiples vistas que usen el mismo modelo, o puedes querer usar un nombre diferente de variable de plantilla si book_list no resulta intuitivo para tu caso particular de uso de plantilla. Posiblemente la variación más útil es cambiar/filtrar el conjunto de resultados que se devuelve, así, en lugar de listar todos los libros podrías listar los 5 libros más leídos por otros usuarios.

+ +
class BookListView(generic.ListView):
+    model = Book
+    context_object_name = 'my_book_list'   # your own name for the list as a template variable
+    queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+    template_name = 'books/my_arbitrary_template_name_list.html'  # Specify your own template name/location
+ +

Sobreescribiendo métodos en vistas basadas en clases

+ +

Si bien no necesitamos hacerlo aquí, puedes también sobreescribir algunos de los métodos de clase.

+ +

Por ejemplo, podemos sobreescribir el método get_queryset() para cambiar la lista de registros devueltos. Esto es más flexible que simplemente ajustar el atributo queryset como lo hicimos en el fragmento de código anterior (aunque en este caso no existe un beneficio real):

+ +

 

+ +
class BookListView(generic.ListView):
+    model = Book
+
+    def get_queryset(self):
+        return Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+
+ +

 

+ +

Podríamos también sobreescribir get_context_data() con el objeto de pasar variables de contexto adicionales a la plantilla (ej. la lista de libros se pasa por defecto). El fragmento de abajo muestra cómo añadir una variable llamada "some_data" al contexto (la misma estaría entonces disponible como una variable de plantilla).

+ +
class BookListView(generic.ListView):
+    model = Book
+
+    def get_context_data(self, **kwargs):
+        # Call the base implementation first to get a context
+        context = super(BookListView, self).get_context_data(**kwargs)
+        # Get the blog from id and add it to the context
+        context['some_data'] = 'This is just some data'
+        return context
+ +

Cuando se hace esto es importante seguir este patrón:

+ + + +
+

Nota: Revisa Built-in class-based generic views (Django docs) para muchos más ejemplos de lo que puedes hacer.

+
+ +

Creando la plantilla de Vista de Lista

+ +

Crea el archivo HTML /locallibrary/catalog/templates/catalog/book_list.html y copia allí el texto de abajo. Como se discutió antes, este es el archivo de plantilla por defecto esperado por la vista de lista genérica basada en clases (para un modelo llamado Book en una aplicación llamada catalog).

+ +

Las plantillas para las vistas genéricas son como cualquier otra plantilla (si bien el contexto/información enviada a la plantilla puede variar, por supuesto). Como con nuestra plantilla índice, extendemos nuestra plantilla base en la primera línea, y luego reemplazamos el bloque llamado content.

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+    <h1>Book List</h1>
+
+    {% if book_list %}
+    <ul>
+
+      {% for book in book_list %}
+      <li>
+        <a href="\{{ book.get_absolute_url }}">\{{ book.title }}</a> (\{{book.author}})
+      </li>
+      {% endfor %}
+
+    </ul>
+    {% else %}
+      <p>There are no books in the library.</p>
+    {% endif %} 
+{% endblock %}
+ +

La vista envía el contexto (lista de libros) por defecto como object_list y book_list (son áliases, cualquiera de ellos funcionará).

+ +

Ejecución condicional

+ +

Usamos las etiquetas de plantilla if, else y endif para revisar si la book_list ha sido definida y no está vacía. Si book_list está vacía, entonces la cláusula else despliega un texto que explica que no existen libros a listar. Si Book_list no está vacía, entonces iteramos a través de la lista de libros.

+ +
{% if book_list %}
+  <!-- code here to list the books -->
+{% else %}
+  <p>There are no books in the library.</p>
+{% endif %}
+
+ +

La condicional de arriba solo revisa un caso, pero puedes revisar condiciones adicionales usando la etiqueta de plantilla elif (ej. {% elif var2 %}). Para mayor información sobre operadores condicionales mira: if, ifequal/ifnotequal, y ifchanged en Built-in template tags and filters (Django Docs).

+ +

Lazos For

+ +

La plantilla usa las etiquetas de plantilla for y endfor para iterar a través de la lista de libros, como se muestra abajo. Cada iteración asigna a la variable de plantilla book la información para el ítem actual de la lista.

+ +
{% for book in book_list %}
+  <li> <!-- code here get information from each book item --> </li>
+{% endfor %}
+
+ +

Si bien no se usan aquí, Django creará otras variables dentro del lazo que puedes usar para monitorear la iteración. Por ejemplo, puedes revisar la variable forloop.last para realizar un procesamiento condicional la última vez que el lazo se ejecuta.

+ +

Accediendo a las variables

+ +

El código dentro del lazo crea un ítem de lista para cada libro, que muestra tanto el título (como un enlace hacia la vista de detalle que aún no creamos) como el autor.

+ +
<a href="\{{ book.get_absolute_url }}">\{{ book.title }}</a> (\{{book.author}})
+
+ +

Accedemos a los campos del registro del libro asociado usando la "notación de punto" (ej. book.title y book.author), donde el texto que sigue a la palabra book es el nombre del campo (como se definió en el modelo).

+ +

También podemos invocar funciones en el modelo desde dentro de nuestra plantilla -- en este caso invocamos a book.get_absolute_url() para obtener una URL que se podría usar para desplegar la página de detalle relacionada. Esto funciona siempre y cuando la función no tenga ningún argumento (¡no hay forma de enviar argumentos!).

+ +
+

Nota: Debemos tener cuidado de los "efectos secundarios" al invocar funciones en las plantillas. Aquí solo obtenemos una URL para desplegar, pero una función puede hacer casi cualquier cosa -- ¡no quisieramos borrar nuestra base de datos (por ejemplo) solo por renderizar nuestra plantilla!

+
+ +

Actualizar la plantilla base

+ +

Abre la plantilla base (/locallibrary/catalog/templates/base_generic.html) e inserta {% url 'books' %} en el enlace URL para All books, como se muestra abajo. Esto habilitará el enlace en todas las páginas (podemos ubicar esto exitosamente en su lugar ahora que hemos creado el mapeo url "books").

+ +
<li><a href="{% url 'index' %}">Home</a></li>
+<li><a href="{% url 'books' %}">All books</a></li>
+<li><a href="">All authors</a></li>
+ +

¿Cómo se ve?

+ +

Aún no podrás ver la lista de libros, porque aún nos falta una dependencia -- el mapeo URL para las páginas de detalle de libros, que se necesita para crear los hipervínculos a los libros individuales. Mostraremos tanto la lista de libros como las vistas de detalle después de la siguiente sección.

+ +

Página de detalle de libros

+ +

La página de detalle de libro desplegará información sobre un libro específico, a la que se accede usando la URL catalog/book/<id> (donde <id> es la clave primaria para el libro). Además de los campos en el modelo Book (autor, resumen, ISBN, idioma, y género), listaremos también los detalles de las copias disponibles (BookInstances) incluyendo su estado, fecha de devolución esperada, edición e id. Esto permitirá a nuestros lectores no solo saber sobre el libro en sí, sino también confirmar si está disponible o cuándo lo estará.

+ +

Mapeo URL

+ +

Abre /catalos/urls.py y añade el mapeador URL 'book-detail' que se muestra abajo en negrita. Esta función url() define un patrón, vista de detalle genérica basada en clases asociada, y un nombre.

+ +
urlpatterns = [
+    url(r'^$', views.index, name='index'),
+    url(r'^books/$', views.BookListView.as_view(), name='books'),
+    url(r'^book/(?P<pk>\d+)$', views.BookDetailView.as_view(), name='book-detail'),
+]
+ +

A diferencia de nuestros mapeadores anteriores, en este caso estamos usando nuestra expresión regular (RE) para comparar frente a un "patrón" real en lugar de una simple cadena. Lo que hace esta RE en particular es coincidir con cualquier URL que empiece por book/, seguido de uno o más dígitos (números) antes del marcador de fin de línea. Mientras se realiza la comparación, se "capturan" los dígitos y son enviados a la función de vista como un parámetro llamado pk.

+ +
+

Nota: Como ya se discutió antes, nuestra URL coincidente es en realidad catalog/book/<digits> (como estamos en la aplicación catalog, se asume /catalog/).

+
+ +
+

Importante: La vista de detalle genérica basada en clases espera que se le envíe un parámetro llamado pk. Si estás escribiendo tu propia vista de función, puedes usar el nombre de parámetro que quieras, o incluso enviar la información como un argumento sin nombre.

+
+ +

Una breve introducción a las expresiones regulares

+ +

Las expresiones regulares son una herramienta de mapeo de patrones increíblemente poderosa. Hemos dicho poco sobre ellas hasta ahora porque estuvimos comparando con cadenas fijas en nuestras URLs (en lugar de con patrones) y porque son, francamente, bastante intuitivas e intimidantes para los principiantes.

+ +
+

Nota: ¡No te asustes! Los tipos de patrones con los que estaremos comparando son bastante simples, ¡y en muchos casos están bien documentados!

+
+ +

Lo primero que hay que saber es que las expresiones regulares deberían ser declaradas normalmente usando la sintaxis de literal de cadena sin procesar (esto es, están encerradas así: r'<tu expresión regular va aquí>').

+ +

Las partes principales de la sintaxis que necesitarás saber para declarar las coincidencias de patrones son:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SímboloSignificado
^Coincide con el inicio del texto
$Coincide con el fin del texto
\dCoincide con un dígito (0, 1, 2, ... 9)
\w +

Concide con un caracter de palabra, ej. cualquier caracter del alfabeto en mayúscula o minúscula, dígito o guión bajo (_)

+
+ +

Concide con uno o más caracteres del precedente. Por ejemplo, para coincidir con uno o más dígitos usarías \d+. Para concidir con uno o más caracteres "a", podrías usar a+

+
* +

Concide con cero o más caracteres del precedente. Por ejemplo, para coincidir con nada o una palabra podrías usar \w*

+
( ) +

Captura la parte del patrón dentro de los paréntesis. Todos los valores capturados serán enviados a la vista como parámetros sin nombre (si se captura múltiples patrones, los parámetros asociados serán enviados en el  órden en que fueron declaradas las capturas).

+
(?P<name>...) +

Captura el patrón (indicado por ...) como una variable con nombre (en este caso "name"). Los valores capturados se envían a la vista con el nombre especificado. Tu vista debe, por tanto, ¡declarar un argumento con el mismo nombre!

+
[  ] +

Concide con un caracter del conjunto. Por ejemplo, [abc] coincidirá con 'a' o 'b' o 'c'. [-\w] coincidrá con el caracter '-' o con cualquier letra.

+
+ +

¡La mayoría de los caracteres restantes se pueden tomar literalmente!

+ +

Consideremos algunos ejemplos reales de patrones:

+ + + + + + + + + + + + + + + + + + + + + + +
PatrónDescripción
r'^book/(?P<pk>\d+)$' +

Esta es la RE usada en nuestro mapeador url. Concide con una cadena que tiene book/ al inicio de la línea (^book/), luego tiene uno o más dígitos (\d+), y luego termina (sin ningún caracter que no sea un dígito antes del marcador de fin de línea).

+ +

También captura todos los dígitos (?P<pk>\d+) y los envía a la vista como un parámetro llamado 'pk'. ¡Los valores capturados siempre se envían como cadena!

+ +

Por ejemplo, esto coincidiría con book/1234, y enviaría una variable pk='1234' a la vista.

+
r'^book/(\d+)$' +

Esta expresión coincide con las mismas URLs que el caso anterior. La información capturada se enviaría a la vista como un argumento sin nombre.

+
r'^book/(?P<stub>[-\w]+)$' +

Esta expresión coincide con una cadena que tiene book/ al inicio de la línea (^book/), luego tiene uno o más caracteres que son o bien '-' o una letra ([-\w]+), y luego termina. También captura este conjunto de caracteres y los envía a la vista como un parámetro llamado 'stub'.

+ +

Este es un patrón bastante típico para un "talón". Estos talones representan claves primarias en URLs amigables basadas en palabras para la información. Podrías usar un talón si quisieras que la URL de un libro sea más informativa. Por ejemplo, /catalog/book/the-secret-garden en lugar de /catalog/book/33.

+
+ +

Puedes capturar múltiples patrones en una sola comparación, y por tanto codificar bastantes datos diferentes en una URL.

+ +
+

Nota: Como reto, considera cómo podrías codificar una url para listar todos los libros publicados en un año, mes y día en particular, y la RE que podría usarse para la comparación.

+
+ +

Enviado opciones adicionales en tus mapeos URL

+ +

Una característica que no hemos usado aquí, pero que te puede resultar valiosa, es que puedes declarar y enviar opciones adicionales a la vista. Las opciones se declaran como un diccionario que envías como el tercer argumento sin nombre a la función url(). Esta estrategia puede resultar útil si quiere usar la misma vista para múltiples recursos, y enviar información para configurar su comportamiento en cada caso (abajo suministramos una plantilla diferente en cada caso).

+ +
url(r'^/url/$', views.my_reused_view, {'my_template_name': 'some_path'}, name='aurl'),
+url(r'^/anotherurl/$', views.my_reused_view, {'my_template_name': 'another_path'}, name='anotherurl'),
+
+
+ +
+

Nota: Tanto las opciones extra como los patrones capturados con nombre se envían a la vista como argumentos con nombre. Si usas el mismo nombre tanto para un patrón capturado como para una opción extra, solo el valor del patrón capturado será enviado a la vista (el valor especificado para la opción extra será eliminado).

+
+ +

Vista (basada en clases)

+ +

Abre catalog/views.py y copia el siguiente código al final del archivo:

+ +
class BookDetailView(generic.DetailView):
+    model = Book
+ +

¡Eso es todo! Lo único que necesitas hacer ahora es crear una plantilla llamada /locallibrary/catalog/templates/catalog/book_detail.html, y la vista enviará la información en la base de datos para el registro del libro específico, extraído por el mapeador URL. Dentro de la plantilla puedes acceder a la lista de libros mediante la variable de plantilla llamada object o book (esto es, genéricamente, "el_nombre_del_modelo").

+ +

Si lo necesitas puedes cambiar la plantilla usada y el nombre del objeto de contexto usado para referenciar al libro en la plantilla. Puedes también sobreescribir métodos para, por ejemplo, añadir información adicional al contexto.

+ +

¿Qué sucede si el registro no existe?

+ +

Si un registro solicitado no existe, la vista de detalle genérica basada en clases lanzará automáticamente por tí una excepción de tipo Http404 -- en producción, esto desplegará automáticamente una página apropiada de "recurso no encontrado", que puedes personalizar si lo deseas.

+ +

Solo para darte una idea sobre cómo funciona esto, el fragmento de código de abajo demuestra cómo implementarías la vista basada en clases como una función, si no estuvieras usando la vista de detalle genérica basada en clases.

+ +
def book_detail_view(request,pk):
+    try:
+        book_id=Book.objects.get(pk=pk)
+    except Book.DoesNotExist:
+        raise Http404("Book does not exist")
+
+    #book_id=get_object_or_404(Book, pk=pk)
+
+    return render(
+        request,
+        'catalog/book_detail.html',
+        context={'book':book_id,}
+    )
+
+ +

Primero, la vista intenta recuperar el registro del libro específico desde el modelo. Si esto falla, la vista debería lanzar una excepción de tipo Http404 para indicar que el libro "no se encuentra". El último paso es, como de costumbre, llamar a render() con el nombre de la plantilla y la información del libro en el parámetro context (como un diccionario).

+ +
+

Nota: get_object_or_404() (que se muestra comentado arriba), es un atajo conveniente para lanzar una excepción de tipo Http404 si el registro no se encuentra.

+
+ +

Creando la plantilla de Vista de Detalle

+ +

Crea el archivo HTML /locallibrary/catalog/templates/catalog/book_detail.html y ponle el contenido de abajo. Como se discutió antes, este es el nombre de archivo por defecto esperado por la vista de detalle genérica basada en clases (para un modelo llamado Book en una aplicación llamada catalog).

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+  <h1>Title: \{{ book.title }}</h1>
+
+  <p><strong>Author:</strong> <a href="">\{{ book.author }}</a></p> <!-- author detail link not yet defined -->
+  <p><strong>Summary:</strong> \{{ book.summary }}</p>
+  <p><strong>ISBN:</strong> \{{ book.isbn }}</p>
+  <p><strong>Language:</strong> \{{ book.language }}</p>
+  <p><strong>Genre:</strong> {% for genre in book.genre.all %} \{{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}</p>
+
+  <div style="margin-left:20px;margin-top:20px">
+    <h4>Copies</h4>
+
+    {% for copy in book.bookinstance_set.all %}
+    <hr>
+    <p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">\{{ copy.get_status_display }}</p>
+    {% if copy.status != 'a' %}<p><strong>Due to be returned:</strong> \{{copy.due_back}}</p>{% endif %}
+    <p><strong>Imprint:</strong> \{{copy.imprint}}</p>
+    <p class="text-muted"><strong>Id:</strong> \{{copy.id}}</p>
+    {% endfor %}
+  </div>
+{% endblock %}
+ + + +
+

El enlace author en la plantilla de arriba tiene una URL vacía porque no hemos creado aún una página de detalle de autor. Una vez que esta exista, deberías actualizar la URL así:

+ +
<a href="{% url 'author-detail' book.author.pk %}">\{{ book.author }}</a>
+
+
+ +

Aunque es un poco más larga, casi todo lo que existe en esta plantilla se ha descrito previamente:

+ + + +

Lo interesante que no hemos visto previamente es la función book.bookinstance_set.all(). Este método es "automágicamente" creado por Django para devolver el conjunto de registros de BookInstance asociado con un Book en particular.

+ +
{% for copy in book.bookinstance_set.all %}
+<!-- code to iterate across each copy/instance of a book -->
+{% endfor %}
+ +

Este método es necesario porque has declarado un campo ForeignKey (uno-a-muchos) únicamente en la lado "uno" de la relación. Como no haces nada para declarar la relación en el otro modelo ("muchos"), este no tiene ningún campo para obtener el conjunto de registros asociados. Para superar este problema, Django construye una función apropiadamente llamada "búsqueda reversa" que puedes usar. El nombre de la función se construye convirtiendo a minúsculas el nombre del modelo donde la ForeignKey fue declarada, seguido por _set (así, la función creada en Book es bookinstance_set()).

+ +
+

Nota: Aquí usamos all() para obtener todos los registros (la opción por defecto). A pesar de que puedes usar el método filter() para obtener un subconjunto de registros en el código, no puedes hacerlo directamente en las plantillas porque no puedes especificar argumentos para las funciones.

+ +

Ten también cuidado de que si no defines un orden (en tu vista o modelo basado en clases), verás errores arrojados por el servidor de dearrollo como este:

+ +
[29/May/2017 18:37:53] "GET /catalog/books/?page=1 HTTP/1.1" 200 1637
+/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <QuerySet [<Author: Ortiz, David>, <Author: H. McRaven, William>, <Author: Leigh, Melinda>]>
+  allow_empty_first_page=allow_empty_first_page, **kwargs)
+
+ +

Eso sucede porque el objeto paginador espera ver una cláusula ORDER BY siendo ejecutada en tu base de datos subyacente. Sin ella, ¡no puede estar seguro de que los registros devueltos están en el orden correcto!

+ +

Este tutorial no llegó a la Paginación (aún, pero pronto lo hará), pero como no puedes uar sort_by() y enviar un parámetro (el mismo con filter() descrito arriba) tendrás que escoger entre tres opciones:

+ +
    +
  1. Añadir un ordering dentro de una declaración class Meta en tu modelo.
  2. +
  3. Añadir un atributo queryset en tu vista basada en clases personalizada, especificando un order_by().
  4. +
  5. Añadir un método get_queryset a tu vista basada en clases pesonalizada y también especificar el order_by().
  6. +
+ +

Si te decides por la opción class Meta para el modelo Author (probablemente no tan flexible como personalizar la vista basada en clases, pero lo suficientemente fácil), terminarás con algo como esto:

+ +
class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return '%s, %s' % (self.last_name, self.first_name)
+
+    class Meta:
+        ordering = ['last_name']
+ +

Por supuesto, el campo no tiene que ser last_name: podría ser cualquier otro.

+Y por último, pero no menos importante, deberías ordenar por un atributo/columna que tenga un índice real (único o no) en tu base de datos para evitar problemas de rendimiento. Por supuesto, esto no será necesario aquí (y probablemente nos estemos adelantando mucho) para la pequeña cantidad de libros (¡y usuarios!), pero es algo a tener en cuenta para proyectos futuros.
+ +

¿Cómo se ve?

+ +

En este punto deberíamos haber creado todo lo necesario para desplegar tanto la lista de libros como las páginas de detalles de libros. Ejecuta el servidor (python3 manage.py runserver) y dirígete en tu navegador a http://127.0.0.1:8000/.

+ +
+

Advertencia: No hagas click aún en ningún enlace de autor o de detalles de autores -- ¡los crearás en el reto!

+
+ +

Haz click en el enlace All books para desplegar la lista de libros.

+ +

Book List Page

+ +

Luego haz click en un enlace a uno de tus libros. Si todo está correcto, deberías ver algo como la siguiente pantalla.

+ +

Book Detail Page

+ +

Paginación

+ +

Si apenas tienes unos pocos registros, nuestra página de lista de libros se verá bien. Sin embargo, cuando llegues a las decenas o centenas de registros la página tomará progresivamente más tiempo en cargar (y tendrá demasiado contenido para navegar adecuadamente). La solución a este problema es añadir paginación a tus vistas de lista, reduciendo el número de Ítems desplegados en cada página.

+ +

Django incluye un excelente soporte para paginación. Mejor aún, este está incluído en las vistas de lista genéricas basadas en clases, ¡así que no tienes que hacer mucho para habilitarlo!

+ +

Vistas

+ +

Abre catalog/views.py, y añadie la línea paginate_by que se muestra abajo en negrita.

+ +
class BookListView(generic.ListView):
+    model = Book
+    paginate_by = 10
+ +

Con esta adición, apenas tengas más de 10 registros la vista comenzará a paginar la información que envía a la plantilla. A las diferentes páginas se accede usando parámetros GET -- para acceder a la página 2 usarías la URL: /catalog/books/?page=2.

+ +

Plantillas

+ +

Ahora que la información está paginada, necesitamos añadir soporte a la plantilla para desplazarse a través del conjunto de resultados. Como podríamos querer hacer lo mismo en todas las vistas de lista, lo haremos de una forma en la que puede ser añadida a la plantilla base.

+ +

Abre /locallibrary/catalog/templates/base_generic.html y copia el siguiente bloque pagination debajo de nuestro bloque content (resaltado abajo en negrita). El código primero revisa si la paginación está habilitada en la página actual. Si lo está, añade enlaces next y previous apropiados (y el número de la página actual).

+ +
{% block content %}{% endblock %}
+
+{% block pagination %}
+  {% if is_paginated %}
+      <div class="pagination">
+          <span class="page-links">
+              {% if page_obj.has_previous %}
+                  <a href="\{{ request.path }}?page=\{{ page_obj.previous_page_number }}">previous</a>
+              {% endif %}
+              <span class="page-current">
+                  Page \{{ page_obj.number }} of \{{ page_obj.paginator.num_pages }}.
+              </span>
+              {% if page_obj.has_next %}
+                  <a href="\{{ request.path }}?page=\{{ page_obj.next_page_number }}">next</a>
+              {% endif %}
+          </span>
+      </div>
+  {% endif %}
+{% endblock %} 
+ +

page_obj es un objeto Paginator que existirá si se usa la paginación en la página actual. Te permite obtener toda la información sobre la página actual, páginas anteriores, cuántas páginas hay, etc.

+ +

Usamos \{{ request.path }} para obtener la URL de la página actual para crear a su vez los enlaces de paginación. Esto es útil, porque es independiente del objeto que estamos paginando.

+ +

¡Eso es todo!

+ +

¿Cómo se ve?

+ +

La captura de pantalla de abajo muestra cómo se ve la paginación -- si no has ingresado más de 10 títulos en tu base de datos, puedes probarlo más fácilmente reduciendo el número especificado en la línea paginate_by en tu archivo catalog/views.py. Para obtener el resultado de abajo lo cambiamos a paginate_by = 2.

+ +

Los enlaces de paginación se muestran en la parte de abajo, con enlaces de next/previous desplegados dependiendo de en qué página estés

+ +

Book List Page - paginated

+ +

Rétate a tí mismo

+ +

El reto en este artículo es crear las vistas de lista y detalle para autores, que se requieren para completar el proyecto. Estas deberían estar disponibles en las siguientes URLs:

+ + + +

El código requerido para los mapeadores URL y las vistas debería ser virtualmente idéntico a las vistas de lista y detalle para Book que creamos arriba. Las plantillas serán diferentes, pero tendrán un comportamiento similar.

+ +
+

Nota:

+ + + +
<p><strong>Author:</strong> <a href="{% url 'author-detail' book.author.pk %}">\{{ book.author }}</a></p> 
+
+ +

Cuando termines, tus páginas deberían lucir similares a las capturas de pantalla de abajo.

+ +

Author List Page

+ + + +

Author Detail Page

+ + + +

Resumen

+ +

Felicitaciones, ¡la funcionalidad de nuestra biblioteca básica está ahora completa!

+ +

En este artículo hemos aprendido cómo usar las vistas genéricas basadas en clases de lista y detalle, y las hemos usado para crear páginas para ver nuestros libros y autores. Sobre la marcha hemos aprendido sobre coincidencia de patrones con expresiones regulares, y cómo puedes enviar información desde las URLs a tus vistas. Hemos también aprendido unos cuantos trucos más para usar plantillas. Por último hemos mostrado cómo paginar vistas de lista, de modo que nuestras listas sean manejables incluso si tenemos muchos registros.

+ +

En los siguientes artículos extenderemos esta biblioteca para añadir soporte para cuentas de usuario, y así demostrar la autenticación de usuarios, permisos, sesiones y formularios.

+ +

Mira también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}

+ +

 

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/home_page/index.html b/files/es/learn/server-side/django/home_page/index.html new file mode 100644 index 0000000000..4c849e8917 --- /dev/null +++ b/files/es/learn/server-side/django/home_page/index.html @@ -0,0 +1,403 @@ +--- +title: 'Tutorial de Django Parte 5: Creación de tu página de inicio' +slug: Learn/Server-side/Django/Home_page +translation_of: Learn/Server-side/Django/Home_page +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}
+ +

Estamos listos ahora para añadir el código para mostrar nuestra primera página entera — una página de inicio del sitio web de la BibliotecaLocal que muestra cuántos registros tenemos de cada tipo de modelo y proporciona una barra lateral con enlaces de navegación a nuestras otras páginas. Por el camino ganaremos experiencia práctica en escritura básica de mapeos de URL y vistas, obtención de resgistros de la base de datos y uso de plantillas.

+ + + + + + + + + + + + +
Pre-requisitos:Lee la Introducción a Django. Completa los tópicos previos del tutorial (incluyendo Tutorial de Django Parte 4: Sitio de administración de Django).
Objetivo: +

Entender cómo crear mapas url y vistas simples (sin información codificada en la URL), y cómo obtener información desde los modelos y crear plantillas.

+
+ +

Visión General

+ +

Ahora que hemos definindo nuestros modelos y hemos creado los primeros registros en la librería para trabajar, es hora de escribir código para presentar información a los usuarios. Lo primero que necesitamos es determinar que información queremos mostrar en nuestras páginas, y definir una URL apropiada hacia estos recursos. Vamos a necesitar crear el mapeador de URLs, las vistas y plantillas para mostrar estas páginas.

+ +

El siguiente diagrama es un recordatorio del principal flujo de datos y cosas necesarias para ser implementadas cuando se maneja una respuesta/petición en HTTP.
+ Los principales elementos que necesitamos crear son:

+ + + +

+ +

Como verás en la siguiente sección, vamos a tener 5 páginas para mostrar, que es mucho que documentar en un artículo. Por lo tanto, en la mayor parte de este artículo nos concentraremos en mostrar como implementar solo la página de inicio (nos moverermos a otras páginas en un artículo subsecuente). Esto debe darte un buen entendimiento de extremo a extremo sobre como los mapeadores URL, vistas y modelos funcionan en la práctica.

+ +

Definiendo el recurso URL

+ +

Como esta versión de LocalLibrary  es escencialmente solo de lectura para usuarios finales, debemos proveer una página de llegada para el sitio (una página de inicio), y páginas que desplieguen listas y vistas detalladas para libros y autores. 

+ +

Las URL que vamos a necesitar para nuestras páginas son:

+ + + +

La tres primeras URLs son usadas para listar el índice, los libros y autores. Esto no codifica ninguna información adicional, y mientras los resultados retornados dependerán del contenido en la base de datos, las consultas que se ejecutan para obtener la información siempre serán las mismas.

+ +

En contraste las 2 URLs finales son usadas para mostrar información detallada sobre un libro o autor específico — estas codifican la identidad de los ítemes a mostrar en la URL (mostrado arriba como <id> ). El mapeador URL puede extraer la información codificada y pasársela a la vista, donde se detarminará que información extraer de la base de datos. Al codificar la información en nuestra URL solo necesitamos un mapeador de URL, una vista, y un plantilla para manejar cada libro (o autor). 

+ +
+

Nota: Django te permite construir tus URLs  de cualquier forma que quieras — puedes codificar información en el cuerpo de la URL como se muestra arriba o usando la obtención de  parámetros GET  de la URL(e.j. /book/?id=6). Culquier enfoque que uses, las URLs deben mantenerse limpias, lógicas y legibles (observa el consejo del W3C aquí).
+
+ La documentación Django tiende a recomendar la codificación de información en el cuerpo de la URL, una práctica que ellos creen que promueve mejores diseños de URL.

+
+ +

Como discutimos en la introducción, el resto de este articulo describe como construimos la página index.

+ +

Creando la página index

+ +

La primera página que crearemos será la página index (catalog/). Esto desplegará un pequeño HTML estático, junto con algunos "contadores" calculados de diferentes registros en la base de datos. Para hacer este trabajo tendremos que crear un mapeador URL, una vista y una plantilla. 

+ +
+

Nota: Vale la pena prestar un poco de atención extra en esta sección. La mayoría del contenido es común para todas las páginas.

+
+ +

Mapeador URL

+ +

Hemos creado un archivo básico /catalog/urls.py para nuestra aplicación catálogo cuando creamos el esqueleto del sitio Web. Las URLs de la aplicación catálogo fueron incluidas dentro del proyecto con un mapeador a catalog/, entonces las URLs  que llegan a este mapeador deben empezar con catalog/ (el mapeador funciona sobre todos los string en la URL después de la barra diagonal).

+ +

Abra urls.py y pegue la línea en negrita que aparece a continuación. 

+ +
urlpatterns = [
+    url(r'^$', views.index, name='index'),
+]
+ +

Esta función url() define un patrón URL (r'^$'),  y una función vista que será llamada si el patrón es detectado (views.index — una función llamada index() en views.py). El patrón URL es una expresión regular de Python (ER). Hablaremos un poco más sobre ERs más adelante en este tutorial, pero para este caso todo lo que necesitas saber es que en una ER de ^$  el patrón coincidirá con una cadena vacía  (^ es un marcador de inicio de cadena y  $ es un marcador de fin de cadena). 

+ +
+

Nota: Nota que en  /locallibrary/locallibrary/urls.py 

+ +
urlpatterns += [
+    url(r'^catalog/', include('catalog.urls')),
+]
+ +

La expresión regular en este caso no tienen un $ (caracter asignado a fin-de-cadena) pero incluye una barra diagonal. Siempre cuando Django se encuentra con include() (django.conf.urls.include()), corta cualquier parte de la URL que coincida hasta este punto y envía el resto de la cadena para incluir la configuración URL para el siguiente procesamiento.

+ +

La URL coincidente es en realidad catalog/ + <cadena vacía> ( /catalog/ es asumida ya que include() fue el método usado). Nuestra primera función vista  será llamada si recibimos una consulta HTTP con una URL de /catalog/.

+
+ +

La función  url() también especifica un parámetro name, que identifica de manera única  este mapeador de URL particular. Puedes usar este nombre para "revertir" el mapeador — para crear dinámicamente una URL que apunta al el recurso que el mapeador esta diseñado para manejar. Por ejemplo, con esto hecho ahora podemos enlazar nuestra página inicio creando el siguiente enlace en nuestra plantilla:

+ +
<a href="{% url 'index' %}">Home</a>.
+ +
+

Nota: Por su puesto podemos codificar a fuerza bruta el link anterior (e.j. <a href="/catalog/">Home</a>), pero entonces si cambiamos el patrón para nuestra página de inicio (e.j. a /catalog/index) la plantilla no podrá seguir enlazando correctamente. Usar un mapeador de url es mucho más flexible y robusto!

+
+ +

Vista (basada-en-funciones)

+ +

Una vista es una función que procesa una consulta HTTP, trae datos desde la base de datos cuando los necesita, genera una página HTML renderizando estos datos unando una plantilla HTML, y luego retorna el HTML en una respuesta HTTP para ser mostrada al usuario. La vista del índice sigue este modelo — extrae información sobre cuantos Book, BookInstanceBookInstance disponibles y registros Author tenemos en la base de datos, y los pasa a una plantilla para mostrarlos.

+ +

Abre catalog/views.py, y nota que el archivo ya importa el atajo de la función render() que genera archivos HTML usando una plantilla y datos. 

+ +
from django.shortcuts import render
+
+# Create your views here.
+
+ +

Copia el siguiente código al final del archivo. La primera linea importa las clases de los modelos que usaremos para acceder a los datos en todas nuestras vistas.

+ +
from .models import Book, Author, BookInstance, Genre
+
+def index(request):
+    """
+    Función vista para la página inicio del sitio.
+    """
+    # Genera contadores de algunos de los objetos principales
+    num_books=Book.objects.all().count()
+    num_instances=BookInstance.objects.all().count()
+    # Libros disponibles (status = 'a')
+    num_instances_available=BookInstance.objects.filter(status__exact='a').count()
+    num_authors=Author.objects.count()  # El 'all()' esta implícito por defecto.
+
+    # Renderiza la plantilla HTML index.html con los datos en la variable contexto
+    return render(
+        request,
+        'index.html',
+        context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors},
+    )
+ +

La primera parte de la función vista extrae contadores de registros usando el atributo objects.all() en las clases del modelo. Tambien obtiene una lista de los objetos BookInstance  que tienen un valor del campo status de  'a' (Disponible). Puedes encontrar un poco más sobre cómo acceder desde modelos en nuestro tutorial previo (Django Tutorial Part 3: Usando modelos > Buscando registros).

+ +

Al final de la función invocamos a la función render()  para crear y retornar una página  HTML como una respuesta (esta función atajo envuelve una serie, simplicando este caso de uso muy común). Esta recibe como parametros el objeto request original (una ConsultaHttp), una plantilla HTML con marcadores para los datos, y una variable de contexto (un diccionario Python que contiene los datos que serán insertados en esos marcadores). 

+ +

Hablaremos más sobre la plantilla y la variable de contexto en la siguiente sección; vamos a crear nuestra plantilla para así de hecho mostrarle algo al usuario!

+ +

Plantilla

+ +

Una plantilla es un archivo de texto  que determina la estructura o diseño de un archivo (como una página HTML), con marcadores usados para representar el contenido real. Django automaticamente buscará plantillas en un directorio llamado 'templates' de su aplicación. Así por ejemplo, en la vista índice que acabamos de agregar, la función render() esperará poder encontrar el archivo /locallibrary/catalog/templates/index.html, y entregará un error si el archivo no puede ser encontrado. Puede ver esto si guarda los cambios anteriores y vuelve a su navegador — accediendo a 127.0.0.1:8000 ahora le entregará un mensaje de error bastante intuitivo "TemplateDoesNotExist at /catalog/", más otros detalles.

+ +
+

Nota: Django buscará en una serie de lugares por plantillas, basandose en su archivo de configuraciones de proyectos (buscar en su aplicación instalada es una configuración por defecto!). Puede encontrar más sobre como Django encuentra plantillas y qué formatos de plantillas soporta Templates (Django docs).

+
+ +

Plantillas extendidas

+ +

La plantilla índice va a necesitar marcado HTML estándar para la cabecera y el cuerpo, junto con secciones para navegar (a otras páginas en el sitio que todavía no hemos creado) y para mostrar algún texto introductorio y nuestros datos de libro. La mayoría de este texto (el HTML y la estructura de navegación) será el mismo para cada página en nuestro sitio. En lugar de obligar a los desarrolladores a duplicar este texto en cada página, el lenguaje de plantillas de Django le permite declarar una plantilla base y luego extenderla, reemplazando solo las porciones que son distintos para cada página específica. 

+ +

Por ejemplo, un plantilla base base_generic.html podría verse como el texto de abajo. Como puedes ver, este contiene algo de HTML "común"  y secciones para el título, barra lateral, y contendio marcados usando las etiquetas de plantillas llamadas block y endblock  (mostradas en negrita). Los bloques pueden estar vacíos, o tener contenido que será usado "por defecto" para páginas derivadas.

+ +
+

Nota: Las etiquetas de plantilla son como funciones que puede usar en una plantilla para recorrer listas, realizar operaciones condicionales basadas en el valor de una variable, etc. Además de las etiquetas de plantilla, la sintaxis de plantilla te permite referenciar variables de plantilla (que son pasadas en la plantilla desde la vista)  y usar  filtros de plantilla, que reformatean las variables (por ejemplo, establecer una cadena en minúsculas).

+
+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+  {% block title %}<title>Local Library</title>{% endblock %}
+</head>
+
+<body>
+  {% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
+  {% block content %}<!-- default content text (typically empty) -->{% endblock %}
+</body>
+</html>
+
+ +

Cuando queremos definir una plantilla para una vista en particular, primero especificamos la plantila base  (con la etiqueta de plantilla  extends — vea el código siguiente). Si ahí hay alguna seccón que queremos reemplazar en la plantilla declaramos esto, usando secciones block/endblock  idénticas a las usadas en la plantilla base.

+ +

Por ejemplo, el fragmento de código que sigue muestra como usar la etiqueta de plantilla extends, y sobrescribe el bloque content. El HTML final producido tendrá todo el HTML y la estructura defininda en la plantilla base (incluyendo el contenido por defecto que ha definido dentro del bloque title), pero con tu nuevo bloque content insertado en lugar del que venía por defecto.

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<h1>Local Library Home</h1>
+<p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
+{% endblock %}
+ +

La plantilla base de LocalLibrary

+ +

La plantilla base que pensamos usar para el siito web LocalLibrary se muestra abajo. Como puedes ver, contiene algo de HTML y bloques definidos para title, sidebar y content. Tenemos un título por defecto (que podríamos querer cambiar) y una barra lateral por defecto con enlaces a listas de todos los libros y autores (que probablemente no querramos cambiar, pero hemos dejado abierta la posibilidad de hacerlo si es necesario, poniéndolo en un bloque).

+ +
+

Nota: También introducimos dos etiquetas de plantilla adicionales: url y load static. Se discute sobre ellas en secciones posteriores.

+
+ +

Crea un nuevo archivo -- /locallibrary/catalog/templates/base_generic.html -- y pon en él el siguiente contenido:

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+
+  {% block title %}<title>Local Library</title>{% endblock %}
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+
+  <!-- Add additional CSS in static file -->
+  {% load static %}
+  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
+</head>
+
+<body>
+
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-sm-2">
+      {% block sidebar %}
+      <ul class="sidebar-nav">
+          <li><a href="{% url 'index' %}">Home</a></li>
+          <li><a href="">All books</a></li>
+          <li><a href="">All authors</a></li>
+      </ul>
+     {% endblock %}
+      </div>
+      <div class="col-sm-10 ">
+      {% block content %}{% endblock %}
+      </div>
+    </div>
+
+  </div>
+</body>
+</html>
+ +

La plantilla usa (e incluye) JavaScript y CSS desde Bootstrap para mejorar el diseño y la presentación de la página HTML. Usar Bootstrap u otro framework web del lado del cliente es una manera rápida de crear una página atractiva que puede escalarse bien en diferentes tamaños de navegador, y también nos permite concentrarnos en la presentación de la página sin tener que entrar en ninguno de los detalles -- ¡queremos enfocarnos nada más en el código del lado del servidor aquí!

+ +

La plantilla base también hace referencia a un archivo css local (styles.css) que brinda algo más de estilo. Crea /locallibrary/catalog/static/css/styles.css y pon en él el siguiente contenido:

+ +
.sidebar-nav {
+    margin-top: 20px;
+    padding: 0;
+    list-style: none;
+}
+ +

La plantilla index

+ +

Crea el archivo HTML /locallibrary/catalog/templates/index.html y pon en él el contenido que se muestra abajo. Como puedes ver, extendemos nuestra plantilla base en la primera línea, y luego reemplazamos el bloque content por defecto con uno nuevo para esta plantilla.

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<h1>Local Library Home</h1>
+
+  <p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
+
+<h2>Dynamic content</h2>
+
+  <p>The library has the following record counts:</p>
+  <ul>
+    <li><strong>Books:</strong> \{{ num_books }}</li>
+    <li><strong>Copies:</strong> \{{ num_instances }}</li>
+    <li><strong>Copies available:</strong> \{{ num_instances_available }}</li>
+    <li><strong>Authors:</strong> \{{ num_authors }}</li>
+  </ul>
+
+{% endblock %}
+ +

En la sección Dynamic content hemos declarado marcadores de posición (variables de plantilla) para la información que quisimos incluir desde la vista. Las variables se marcan usando la sintaxis de "doble corchete" o "llaves" (ver lo que está en negrita arriba).

+ +
+

Nota: Puedes reconocer fácilmente si estás trabajando con variables de plantilla o con etiquetas de plantilla (funciones) porque las variables tienen llaves dobles (\{{ num_books }}) mientras que las etiquetas están encerradas entre llaves simples con signos de porcentaje ({% extends "base_generic.html" %}).

+
+ +

Lo importante de todo esto es que estas variables se nombran con las claves que enviamos dentro del diccionario context en la función render() de nuestra vista (mira abajo); estas variables serán reemplazadas por sus valores asociados cuando la plantilla sea renderizada.

+ +
return render(
+    request,
+    'index.html',
+     context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors},
+)
+ +

Referenciando archivos estáticos en las plantillas

+ +

Es probable que uses recursos estáticos en tu proyecto, incluyendo JavaScript, CSS e imágenes. Debido a que la ubicación de estos archivos podría ser desconocida (o podría cambiar), Django te permite especificar la ubicación de los mismos dentro de tus plantillas de forma relativa al parámetro global STATIC_URL (el sitio web esqueleto por defecto establece el valor de STATIC_URL a '/static/', pero puedes elegir alojar los archivos en una red de distribución de contenidos o en cualquier otro lugar).

+ +

Dentro de la plantilla, primero llamas a la etiqueta de plantilla load especificando "static" para añadir esta biblioteca de plantilla (como se muestra abajo). Luego de que static se carga, puedes usar la etiqueta de plantilla static especificando la URL relativa del archivo de interés.

+ +
 <!-- Add additional CSS in static file -->
+{% load static %}
+<link rel="stylesheet" href="{% static 'css/styles.css' %}">
+ +

Si quisieras podrías añadir una imagen a la página de forma similar. Por ejemplo:

+ +
{% load static %}
+<img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="My image" style="width:555px;height:540px;"/>
+
+ +
+

Nota: Los cambios de arriba especifican dónde se localizan los archivos, pero Django no los sirve por defecto. Si bien habilitamos este servicio para el servidor web de desarrollo en el mapeador URL global (/locallibrary/locallibrary/urls.py) cuando creamos el esqueleto del sitio web, aún necesitarás configurar este servicio para producción. Hablaramos de esto más tarde.

+
+ +

Para mayor información sobre el trabajo con archivos estáticos revisa Managing static files (Django docs).

+ +

Enlazando con URLs

+ +

En la plantilla base de arriba se introdujo la etiqueta de plantilla url.

+ +
<li><a href="{% url 'index' %}">Home</a></li>
+
+ +

Esta etiqueta toma el nombre de una función url() llamada en tu archivo urls.py, y valores para cualquier argumento que la vista asociada recibirá desde tal función, y devuelve una URL que puedes usar para enlazar con el recurso.

+ + + +

Configurando adonde buscar las plantillas

+ +

Para que Django encuentre los archivos de plantillas es necesario editar el archivo settings.py agregando el directorio donde creamos nuestras plantillas en el objeto TEMPLATES, como indica la linea en negrita a continuación:

+ +
TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [
+            os.path.join(BASE_DIR, 'templates'),
+        ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+ +

¿Cómo se ve?

+ +

En este punto deberíamos haber creado todo lo necesario para desplegar la página index. Corre el servidor (python3 manage.py runserver) y dirige tu navegador a http://127.0.0.1:8000/. Si todo se configuró correctamente, tu sitio debería verse similar a la siguiente captura de pantalla.

+ +

Index page for LocalLibrary website

+ +
+

Nota: Aún no podrás usar los enlaces All books y All authors porque las URLs, vistas y plantillas para dichas páginas no se han definido (al momento solo hemos insertado marcadores de posición para esos enlaces en la plantilla base_generic.html).

+
+ +

Rétate a tí mismo

+ +

Aquí hay un par de tareas para probar tu familiaridad con consultas a modelos, vistas y plantillas.

+ +
    +
  1. Declara un nuevo bloque title en la plantilla index y cambia el título de la página para coincidir con esta página en particular.
  2. +
  3. Modifica la vista para generar un conteo de géneros y otro de libros que contengan una palabra en particular (no sensible a mayúsculas y minúsculas) y luego añade estos campos a la plantilla.
  4. +
+ + + +

Resumen

+ +

Hemos creado la página de inicio para nuestro sitio -- una página HTML que despliega algunos conteos de registros de la base de datos y contiene enlaces a otras de nuestras páginas que aún nos faltan por crear. Sobre la marcha hemos adquirido mucha información fundamental sobre mapeadores URL, vistas, consultas a la base de datos usando nuestros modelos, cómo enviar información a una plantilla desde nuestra vista, y cómo crear y extender plantillas.

+ +

En nuestro siguiente artículo nos basaremos en nuestro conocimiento para crear las otras cuatro páginas.

+ +

Mira también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}

+ + + +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/index.html b/files/es/learn/server-side/django/index.html new file mode 100644 index 0000000000..6a33f3e0be --- /dev/null +++ b/files/es/learn/server-side/django/index.html @@ -0,0 +1,66 @@ +--- +title: Framework Web Django (Python) +slug: Learn/Server-side/Django +tags: + - Aprendizaje + - Codificación de scripts + - Principiante + - Programación lado servidor + - Python + - django + - introducción +translation_of: Learn/Server-side/Django +--- +
Django es un framework web extremadamente popular y completamente funcional, escrito en Python. El módulo muestra por qué Django es uno de los frameworks de servidores web más populares, cómo configurar un entorno de desarrollo y cómo empezar a usarlo para crear tus propias aplicaciones web.
+ +

Requisitos Previos

+ +

Antes de comenzar este módulo no es necesario tener ningún conocimiento de Django. Tendrás que entender que son la programación web de lado servidor y los frameworks web, idealmente leyendo los temas en nuestro módulo Primeros pasos en la programación de lado servidor de sitios web.

+ +

Se recomienda un conocimiento general de los conceptos de programación y Python, pero no es esencial para entender los conceptos básicos

+ +
+

Nota: Python es uno de los lenguajes de programación más fáciles de leer y entender para los principiantes. Dicho esto, si desea comprender mejor este módulo, hay numerosos libros y tutoriales gratuitos disponibles en Internet (los nuevos programadores pueden querer ver la página de Python for Non Programmers en el wiki de python.org.

+
+ +

Guías

+ +
+
Introducción a Django
+
En este primer artículo de Django respondemos a la pregunta "¿Qué es Django?" y te dará una visión general de lo que hace a este framework web especial. Vamos a esbozar las principales características incluyendo algunas de las funciones avanzadas que no tendremos tiempo de cubrir en detalle en este módulo. También te mostraremos algunos de los principales bloques de construcción de una aplicación de Django, para darte una idea de lo que puedes hacer antes de que continúes configurándolo y comiences a jugar.
+
Puesta en marcha de un entorno de desarrollo de Django
+
Ahora que sabes qué es y para qué sirve Django, te mostraremos cómo configurar y probar un entorno de desarrollo Django en Windows, Linux(Ubuntu), y Mac OS X. Cualquiera que sea el sistema operativo común que estés utilizando, este articulo deberia de ofrecerte lo necesario para iniciarte en el desarrollo de aplicaciones en Django.
+
Tutorial de Django: Sitio web "Biblioteca Local"
+
El primer articulo de nuestra serie de tutoriales explica lo que se aprenderá y proporciona una descripcion general del sitio web de ejemplo "Biblioteca Local" en el cual trabajaremos y evolucionaremos en articulos posteriores.
+
Tutorial de Django Parte 2: Creación del esqueleto de un sitio web
+
Este artículo muestra cómo crear el "esqueleto" de un proyecto de sitio web como base, que luego se puede rellenar con configuraciones, urls, modelos, vistas y plantillas específicas del sitio.
+
Tutorial de Django Parte 3: Uso de modelos
+
Este artículo muestra cómo definir modelos para el sitio web de la Biblioteca Local — los modelos representan las estructuras en las que queremos almacenar los datos de nuestra app, y también permiten a Django almacenar datos en una base por nosotros (y modificarlos más tarde). Se explica qué es un modelo, cómo se declara y alguno de los principales tipos de campo. También se muestra brevemente unas pocas de las múltiples formas con las que puedes acceder al modelo de datos.
+
Tutorial de Django Parte 4: Sitio de Administración de Django
+
Ahora que hemos creado modelos para el sitio web de la Biblioteca Local, usaremos el sito de administración de Django para añadir algunos datos "reales" de libros. Primero te mostraremos cómo registrar los modelos con el sitio de administración, a continuación te mostraremos cómo iniciar sesión y crear algunos datos. Al final te mostramos algunas formas en las que puedes mejorar la presentación del sitio de administración.
+
Tutorial de Django Parte 5: Creación de tu página de inicio
+
Ahora estamos listos para añadir el código para presentar nuestra primera página completa — una página de inicio para la Biblioteca Local que muestra cuántos registros tenemos de cada tipo de modelo y proporciona una barra lateral con enlaces de navegación a otras páginas. A medida que avanzamos ganaremos experiencia práctica en la escritura de mapas URL y vistas, obtención de registros de la base de datos y la utilización de plantillas.
+
Tutorial de Django Parte 6: Listas genéricas y vistas de detalle
+
Este tutorial extiende el sitio web de nuestra Biblioteca Local añadiendo listas y páginas de detalle de libros y autores. Aquí aprenderemos sobre vistas genéricas basadas en clases y se mostrará cómo pueden reducir la cantidad de código que tienes que escribir para casos de uso común. También nos adentraremos en la gestión de URL en gran detalle, mostrando cómo realizar un emparejamiento básico de patrones.
+
Tutorial de Django Parte 7: Framework de sesiones
+
Este tutorial extiende nuestro sitio web de Biblioteca Local añadiendo a nuestra página de inicio un contador de visitas basado en sesión. Este es un ejemplo relativamente simple, pero muestra de verdad cómo puedes usar el framework de sesión para proporcionar un comportamiento presistente para usuarios anónimos en tus propios sitios.
+
Tutorial de Django Parte 8: Autenticación y permisos de Usuario
+
En este tutorial te mostraremos cómo permitir a los usuarios iniciar sesión en tu sitio con sus propias cuentas y cómo controlar lo que pueden hacer y ver, basado en si han iniciado sesión o no y en sus permisos. Como parte de esta demostración extenderemos el sitio web de la Biblioteca Local, añadiendo páginas de inicio y cierre de sesión, y páginas específicas de usuario - y de personal - para ver libros que han sido prestados.
+
Tutorial de Django Parte 9: Trabajo con formularios
+
En este tutorial te mostraremos cómo trabajar con Formularios HTML en Django, y en particular la forma más fácil de escribir formularios para crear, actualizar y borrar instancias de modelos. Como parte de esta demostración extenderemos el sitio web de la Biblioteca Local de manera que los bibliotecarios puedan renovar libros, y crear, actualizar y borrar autores usando sus propios formularios (en vez de usar la aplicación de administración).
+
Tutorial de Django Parte 10: Probando una aplicación web Django
+
A medida que crecen los sitios web se vuelven más difíciles de probar a mano — no sólo hay más para probar, sino que además, a medida que las interacciones entre los componentes se vuelven más complejas, un pequeño cambio en un área puede suponer muchas pruebas adicionales para verificar su impacto en otras áreas. Una forma de mitigar estos problemas es escribir tests automatizados, que pueden ser ejecutados de manera fácil y fiable cada vez que hagas un cambio. Este tutorial muestra cómo automatizar la unidad de pruebas de tu sitio web usando el framework de pruebas de Django.
+
Tutorial de Django Parte 11: Desplegando Django a producción
+
Ahora que has creado (y probado) un impresionante sitio web para la Biblioteca Local, vas a querer instalarlo en un servidor web público de manera que pueda ser accedido por el personal y los miembros de la biblioteca a través de Internet. Este artículo proporciona una visión general de cómo podrías ir buscando un host para desplegar tu sitio web y lo que necesitas hacer para conseguir que tu sitio esté listo en producción.
+
Seguridad de las aplicaciones web Django
+
Proteger los datos de los usuarios es una parte esencial de cualquier diseño de un sitio web. Previamente ya explicamos algunas de las amenazas de seguridad más comunes en el artículo Seguridad Web — este artículo proporciona una demostración práctica de cómo las protecciones integradas de Django gestionan estas amenazas.
+
+ +

Evaluaciones

+ +

La siguiente evaluación comprobará tu comprensión de cómo crear un sitio web usando Django, como se describe en las guías listadas arriba.

+ +
+
Mini Blog Django Hazlo tu mismo
+
En esta evaluación usarás algo del conocimiento que has aprendido en este módulo para crear tu propio blog.
+
diff --git "a/files/es/learn/server-side/django/introducci\303\263n/index.html" "b/files/es/learn/server-side/django/introducci\303\263n/index.html" new file mode 100644 index 0000000000..484b311a2c --- /dev/null +++ "b/files/es/learn/server-side/django/introducci\303\263n/index.html" @@ -0,0 +1,282 @@ +--- +title: Introducción a Django +slug: Learn/Server-side/Django/Introducción +tags: + - Aprendizaje + - CodigoScript + - Principiante + - Programación lado servidor + - Python + - django + - introducción +translation_of: Learn/Server-side/Django/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}
+ +

En este primer artículo de Django responderemos la pregunta ¿Qué es Django? y daremos una visión general de lo que hace que este framework sea tan especial. Vamos a delinear las características principales, incluidas algunas de las funcionalidades avanzadas que no tendremos tiempo de cubrir con detalle en este módulo.  Tambien mostraremos algunos de los componentes principales de una aplicación de Django. (aunque en este momento no cuentes con un entorno de desarrollo en el cual probarlo).

+ + + + + + + + + + + + +
Pre requisitos:Conocimientos basicos en informatica. Una comprensión general de programación del lado del servidor, y en particular de los mecanimos de interacciones cliente-servidor en los sitios web.
Objetivos:Familiarizarse con lo que es Django, que funcionalidad proporciona y los componentes principales de una aplicación Django.
+ +

¿Qué es Django?

+ +

Django es un framework web de alto nivel que permite el desarrollo rápido de sitios web seguros y mantenibles. Desarrollado por programadores experimentados, Django se encarga de gran parte de las complicaciones del desarrollo web, por lo que puedes concentrarte en escribir tu aplicación sin necesidad de reinventar la rueda. Es gratuito y de código abierto, tiene una comunidad próspera y activa, una gran documentación y muchas opciones de soporte gratuito y de pago.

+ +

Django te ayuda a escribir software que es:

+ +
+
Completo
+
Django sigue la filosofía "Baterías incluidas" y provee casi todo lo que los desarrolladores quisieran que tenga "de fábrica". Porque todo lo que necesitas es parte de un único "producto", todo funciona a la perfección, sigue principios de diseño consistentes y tiene una amplia y actualizada documentación.
+
Versátil
+
Django puede ser (y ha sido) usado para construir casi cualquier tipo de sitio web — desde sistemas manejadores de contenidos y wikis, hasta redes sociales y sitios de noticias. Puede funcionar con cualquier framework en el lado del cliente, y puede devolver contenido en casi cualquier formato (incluyendo HTML, RSS feeds, JSON, XML, etc). ¡El sitio que estás leyendo actualmente está basado en Django!
+
+ Internamente, mientras ofrece opciones para casi cualquier funcionalidad que desees (distintos motores de base de datos , motores de plantillas, etc.), también puede ser extendido para usar otros componentes si es necesario.
+
Seguro
+
Django ayuda a los desarrolladores evitar varios errores comunes de seguridad al proveer un framework que ha sido diseñado para "hacer lo correcto" para proteger el sitio web automáticamente. Por ejemplo, Django, proporciona una manera segura de administrar cuentas de usuario y contraseñas, evitando así errores comunes como colocar informaciones de sesión en cookies donde es vulnerable (en lugar de eso las cookies solo contienen una clave y los datos se almacenan en la base de datos) o se almacenan directamente las contraseñas en un hash de contraseñas.
+  
+ Un hash de contraseña es un valor de longitud fija creado al enviar la contraseña a una cryptographic hash function. Django puede validar si la contraseña ingresada es correcta enviándola a través de una función hash y comparando la salida con el valor hash almacenado. Sin embargo debido a la naturaleza "unidireccional" de la función, incluso si un valor hash almacenado se ve comprometido es difícil para un atacante resolver la contraseña original.
+
+ Django permite protección contra algunas vulnerabilidades de forma predeterminada, incluida la inyección SQL, scripts entre sitios, falsificación de solicitudes entre sitios y clickjacking (consulte Seguridad de sitios web para obtener más detalles sobre dichos ataques).
+
Escalable
+
Django usa un componente basado en la arquitectura “shared-nothing” (cada parte de la arquitectura es independiente de las otras, y por lo tanto puede ser reemplazado o cambiado si es necesario). Teniendo en cuenta una clara separación entre las diferentes partes significa que puede escalar para aumentar el tráfico al agregar hardware en cualquier nivel: servidores de cache, servidores de bases de datos o servidores de aplicación. Algunos de los sitios más concurridos han escalado a Django para satisfacer sus demandas (por ejemplo, Instagram y Disqus, por nombrar solo dos).
+
Mantenible
+
El código de Django está escrito usando principios y patrones de diseño para fomentar la creación de código mantenible y reutilizable. En particular, utiliza el principio No te repitas "Don't Repeat Yourself" (DRY) para que no exista una duplicación innecesaria, reduciendo la cantidad de código. Django también promueve la agrupación de la funcionalidad relacionada en "aplicaciones" reutilizables y en un nivel más bajo, agrupa código relacionado en módulos (siguiendo el patrón Model View Controller (MVC)).
+
Portable
+
Django está escrito en Python, el cual se ejecuta en muchas plataformas. Lo que significa que no está sujeto a ninguna plataforma en particular, y puede ejecutar sus aplicaciones en muchas distribuciones de Linux, Windows y Mac OS X. Además, Django cuenta con el respaldo de muchos proveedores de alojamiento web, y que a menudo proporcionan una infraestructura específica y documentación para el alojamiento de sitios de Django.
+
+ +

¿De dónde vino?

+ +

Django fue desarrollado inicialmente entre 2003 y 2005 por un equipo que era responsable de crear y mantener sitios web de periódicos. Después de crear varios sitios, el equipo empezó a tener en cuenta y reutilizar muchos códigos y patrones de diseño comunes. Este código común se convirtió en un framework web genérico, que fue de código abierto, conocido como proyecto "Django" en julio de 2005.

+ +

Django ha continuado creciendo y mejorando desde su primer hito, el lanzamiento de la versión (1.0) en septiembre de 2008, hasta el reciente lanzamiento de la versión 1.11 (2017). Cada lanzamiento ha añadido nuevas funcionalidades y solucionado errores, que van desde soporte de nuevos tipos de bases de datos, motores de plantillas, caching, hasta la adición de funciones genéricas y clases de visualización (que reducen la cantidad de código que los desarrolladores tiene que escribir para numerosas tareas de programación).

+ +
+

Nota: Consulte las notas de lanzamiento en el sitio web de Django para ver qué ha cambiado en las versiones recientes y cúanto trabajo se lleva a cabo para mejorar Django.

+
+ +

Django es ahora un próspero proyecto colaborativo de código abierto, con miles de usuarios y contribuidores. Mientras que todavía presenta algunas características que reflejan su origen, Django ha evolucionado en un framework versátil que es capaz de desarrollar cualquier tipo de sitio web.

+ + + +

No hay una medida de popularidad definitiva y disponible de inmediato de "frameworks de lado servidor" (aunque sitios como Hot Frameworks intentan evaluar la popularidad usando mecanismos como contar el número de proyectos en Github y preguntas en StackOverflow de cada plataforma). Una pregunta mejor es si Django es lo "suficientemente popular" para evitar los problemas de las plataformas menos populares. ¿Continúa evolucionando? ¿Puedes conseguir la ayuda que necesitas? ¿Hay alguna posibilidad de que consigas un trabajo pagado si aprendes Django?

+ +

De acuerdo con el número de sitios que usan Django, el número de gente que contribuye al código base, y el número de gente que proporciona soporte tanto libre como pagado, podemos entonces decir que sí, !Django es un framework popular!

+ +

Los sitios de alto nivel que usan Django incluyen: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest y Open Stack (fuente: Página de inicio de Django).

+ +

¿Es Django dogmático?

+ +

Los frameworks web frecuentemente se refieren a sí mismos como "dogmáticos" ("opinionated") o "no dogmáticos" ("unopinionated").

+ +

Los frameworks dogmáticos son aquellos que opinan acerca de la "manera correcta" de gestionar cualquier tarea en particular. Ofrecen soporte para el desarrollo rápido en un dominio en particular (resolver problemas de un tipo en particular) porque la manera correcta de hacer cualquier cosa está generalmente bien comprendida y bien documentada.

+ +

Sin embargo pueden ser menos flexibles para resolver problemas fuera de su dominio principal, y tienden a ofrecer menos opciones para elegir qué componentes y enfoques pueden usarse.

+ +

Los framewoks no dogmáticos, por contra, tienen muchas menos restricciones sobre el modo mejor de unir componentes para alcanzar un objetivo, o incluso qué componentes deberían usarse. Hacen más fácil para los desarrolladores usar las herramientas más adecuadas para completar una tarea en particular, si bien al coste de que necesitas encontrar esos componentes por tí mismo.

+ +

Django es "dogmático pero no del todo" y por tanto entrega "lo mejor de ambos mundos". Proporciona un conjunto de componentes para gestionar la mayoría de las tareas de desarrollo web y una (o dos) maneras preferidas de usarlos. Sin embargo, la arquitectura desacoplada de Django implica que puedes normalmente escoger y seleccionar de entre numerosas opciones diferentes o añadir soporte para otras completamente nuevas, si lo deseas.

+ +

¿Qué pinta tiene el código de Django?

+ +

En un sitio web tradicional basado en datos, una aplicación web espera peticiones HTTP del explorador web (o de otro cliente). Cuando se recibe una petición la aplicación elabora lo que se necesita basándose en la URL y posiblemente en la información incluida en los datos POST o GET. Dependiendo de qué se necesita quizás pueda entonces leer o escribir información desde una base de datos o realizar otras tareas requeridas para satisfacer la petición. La aplicación devolverá a continuación una respuesta al explorador web, con frecuencia creando dinámicamente una página HTML para que el explorador la presente insertando los datos recuperados en marcadores de posición dentro de una plantilla HTML.

+ +

Las aplicaciones web de Django normalmente agrupan el código que gestiona cada uno de estos pasos en ficheros separados:

+ +

+ + + +
+

Nota: Django se refiere a este tipo de organización como arquitectura Modelo Vista Plantilla "Model View Template (MVT)". Tiene muchas similaridades con la arquitectura más familiar Model View Controller

+
+ + + +

Las secciones de más abajo te darán una idea de la pinta que tienen estas partes principales de una aplicación Django (entraremos en más detalles más adelante en el curso, una vez que hallamos configurado un entorno de desarrollo).

+ +

Enviar la petición a la vista correcta (urls.py)

+ +

Un mapeador URL está normalmente almacenado en un fichero llamado urls.py. En el ejemplo más abajo el mapeador (urlpatterns) define una lista de mapeos entre patrones URL específicos y sus correspondientes funciones de visualización. Si se recibe una Petición HTTP que tiene una URL que empareja un patrón específico (ej. r'^$', más abajo) se realizará una llamada y se pasará la petición a la función de visualización asociada (ej.  views.index).

+ +
urlpatterns = [
+    url(r'^$', views.index),
+    url(r'^([0-9]+)/$', views.best),
+]
+
+ +
+

Nota: Un poco de Python:

+ + +
+ +

Manejar la petición (views.py)

+ +

Las vistas son el corazón de la aplicación web, recibiendo peticiones HTTP de los clientes web y devolviendo respuestas HTTP. Entre éstas, organizan los otros recursos del framework para acceder a las bases de datos, consolidar plantillas, etc.

+ +

El ejemplo más abajo muestra una mínima función de visualización index(), que podría ser llamada por nuestro mapeador de URL de la sección anterior. Al igual que todas las funciones de visualización, recibe un objeto HttpRequest como parámetro (request) y devuelve un objeto HttpResponse. En este caso no hacemos nada con la petición y nuestra respuesta simplemente devuelve una cadena insertada de forma fija en el código. Te mostraremos una petición que hace algo más interesante en la siguiente sección.

+ +
## fichero: views.py (funciones de visualizacion de Django)
+from django.http import HttpResponse
+
+def index(request):
+    # Obtener un HttpRequest - el parametro peticion
+    # Realizar operaciones usando la infomracion de la peticion.
+    # Devolver una HttpResponse
+    return HttpResponse('!Hola desde Django!')
+
+ +
+

Nota: Un poco de Python:

+ + +
+ + + +

Las vistas se almacenan normalmente en un fichero llamado views.py.

+ +

Definir modelos de datos (models.py)

+ +

Las aplicaciones web Django manejan y consultan datos a través de objetos Python referidos como modelos. Los modelos definen la estructura de los datos almacenados, incluyendo los tipos de campos y posiblemente también su tamaño máximo, los valores por defecto, la lista de selección de opciones, texto de ayuda para documentación, etiquetas de texto para formularios, etc. La definición del modelo es independiente de la base de datos subyacente — puedes elegir una entre varias como parte de la configuración de tu proyecto. Una vez que has seleccionado qué base de datos quieres usar, no necesitas en absoluto comunicarte con ella directamente — sólo hay que escribir la estructura de la base y otro código y Django se encarga por tí de todo el trabajo sucio de comunicarse con la base de datos.

+ +

El fragmento de código de más abajo muestra un modelo de Django muy simple para un objeto Team. La clase Team deriva de la clase de django models.Model. Define el nombre de un equipo y su nivel como campos de tipo carácter y especifica un número máximo de caracteres que pueden ser almacenados en cada registro. El team_level puede ser un valor de entre varios, de manera que lo definimos como un campo de opciones y proporcionamos un mapeo entre opciones para mostrar y datos para almacenar, junto con un valor por defecto.

+ +
# filename: models.py
+
+from django.db import models
+
+class Team(models.Model):
+    team_name = models.CharField(max_length=40)
+
+    TEAM_LEVELS = (
+        ('U09', 'Under 09s'),
+        ('U10', 'Under 10s'),
+        ('U11', 'Under 11s'),
+        ...  #list other team levels
+    )
+    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+
+ +
+

Nota: Un poco de Python:

+ + +
+ +

Consultar datos (views.py)

+ +

El modelo de Django proporciona una API de consulta simple para buscar en la base de datos. Esta puede buscar concidencias contra varios campos al mismo tiempo usando diferentes criterios (ej. exacto, insensible a las mayúsculas, mayor que, etc.), y puede soportar sentencias complejas (por ejemplo, puedes especificar que se busque equipos U11 que tengan un nombre de equipo que empiece por "Fr" o termine con "al").

+ +

El fragmento de código de más abajo muestra una función de visualización (manejador de recursos) para presentar en pantalla todos nuestros equipos U09. La línea en negrilla muestra como podemos usar la API de consulta del modelo para filtrar todos los registros donde el campo team_level tenga exactamente el texto 'U09' (fíjate como este criterio se pasa como argumento a la función filter() con el nombre del campo y tipo de coincidencia separados por un doble guion bajo: team_level__exact).

+ +
## filename: views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def index(request):
+    list_teams = Team.objects.filter(team_level__exact="U09")
+    context = {'youngest_teams': list_teams}
+    return render(request, '/best/index.html', context)
+
+ +
+
+ +

Esta función utiliza la función render() para crear la HttpResponse que se envía de vuelta al explorador. Esta función es un atajo; crea un fichero HTML mediante la combinación de una plantilla HTML específica y algunos datos para insertar en ella (proporcionados en la variable "context"). En la siguiente sección mostramos como la plantilla tiene los datos insertados en ella para crear el HTML.

+ +

Renderización de los datos (plantillas HTML)

+ +

Los sistemas de plantillas permiten especificar la estructura de un documento de salida usando marcadores de posición para los datos que serán rellenados cuando se genere la página. Las plantillas se usan con frecuencia para crear HTML, también pueden crear otros tipos de documentos. Django soporta de fábrica tanto su sistema de plantillas nativo como otra biblioteca Python popular llamada Jinja2 (y se puede hacer que soporte otros sistemas si hace falta).

+ +

El fragmento de código de más abajo muestra el aspecto que podría tener la plantilla HTML llamada por la función render() de la sección anterior. Esta plantilla ha sido escrita bajo la suposición de que cuando sea renderizada tendrá acceso a una variable tipo lista llamada youngest_teams (contenida en la variable context dentro de la función render() de más arriba). Dentro del esqueleto HTML tenemos una expresión que primero comprueba que existe la variable youngest_teams, y luego itera sobre ella en un bucle for. En cada iteración la plantilla presenta cada valor del campo team_name del equipo en un elemento {{htmlelement("li")}}.

+ +
## filename: best/templates/best/index.html
+
+<!DOCTYPE html>
+<html lang="en">
+<body>
+
+ {% if youngest_teams %}
+    <ul>
+    {% for team in youngest_teams %}
+        <li>\{\{ team.team_name \}\}</li>
+    {% endfor %}
+    </ul>
+{% else %}
+    <p>No teams are available.</p>
+{% endif %}
+
+</body>
+</html>
+ +

¿Qué más puedes hacer?

+ +

Las secciones prededentes muestran las principales características que usarás en casi todas las aplicaciones web: mapeo de URLs, vistas, modelos y plantillas. Sólo unas pocas de las otras cosas que Django proporciona y que incluyen:

+ + + +

Sumario

+ +

¡Felicidades, has completado el primer paso en tu viaje por Django! Deberías ahora ser consciente de los principales beneficios de Django, algo de su historia y a groso modo la pinta que tienen cada una de las partes principales de una de sus apps. Deberías también haber aprendido unas pocas cosas acerca del lenguaje de programación Python, incluyendo la sintaxis para las listas, funciones y clases.

+ +

Has visto ya algo de código real de Django más arriba, pero a diferencia del código de lado cliente, necesitas configurar un entorno de desarrollo para hacerlo funcionar. Ese será nuestro siguiente paso.

+ +
{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}} +

En este módulo

+ + +
diff --git a/files/es/learn/server-side/django/models/index.html b/files/es/learn/server-side/django/models/index.html new file mode 100644 index 0000000000..95b6c670ea --- /dev/null +++ b/files/es/learn/server-side/django/models/index.html @@ -0,0 +1,490 @@ +--- +title: 'Tutorial Django Parte 3: Uso de modelos' +slug: Learn/Server-side/Django/Models +tags: + - Aprender + - Artículo + - Datos + - Modelo + - Principiante + - Tutorial + - django + - lado-servidor +translation_of: Learn/Server-side/Django/Models +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}
+ +

Este artículo muestra cómo definir modelos para el sitio web de la BibliotecaLocal. En él se explica lo que es un modelo, cómo se declara, y cuáles son algunos de los principales tipos de campos de un modelo. También veremos, brevemente, cuáles son algunas de las maneras en que puede accederse a los datos del modelo.

+ + + + + + + + + + + + +
Pre-requisitos:Tutorial Django Parte 2: Creación del esqueleto del sitio web.
Objetivo: +

Ser capaz de diseñar y crear tus propios modelos, eligiendo de forma apropiada los campos.

+
+ +

Visión general

+ +

Las aplicaciones web de Django acceden y administran los datos a través de objetos de Python a los que se hace referencia como modelos. Los modelos definen la estructura de los datos almacenados, incluidos los tipos de campo y los atributos de cada campo, como su tamaño máximo, valores predeterminados, lista de selección de opciones, texto de ayuda para la documentación, texto de etiqueta para formularios, etc. La definición del modelo es independiente de la base de datos subyacente. puede elegir una de entre varias como parte de la configuración de su proyecto. Una vez que haya elegido la base de datos que desea usar, no necesita hablar directamente con ella. Simplemente escriba la estructura de su modelo y algo de código, y Django se encargará de todo el trabajo sucio, al comunicarse con la base de datos por usted.

+ +

Este tutorial muestra cómo definir y acceder a los modelos para el ejemplo del sitio web LocalLibrary.

+ +

Diseñando los modelos de LocalLibrary

+ +

Antes de dar el salto y comenzar a codificar los modelos, vale la pena tomarse unos minutos para pensar qué datos necesitamos almacenar y cuáles serán las relaciones entre los diferentes objetos.

+ +

Sabemos que tenemos que almacenar información sobre libros (título, resumen, autor, idioma escrito, categoría, ISBN) y que podríamos tener varias copias disponibles (con id único global, estado de disponibilidad, etc.). Es posible que necesitemos almacenar más información sobre el autor que solo su nombre, y puede haber varios autores con el mismo nombre o nombres similares. Queremos poder ordenar la información según el título del libro, el autor, el idioma escrito y la categoría.

+ +

Al diseñar sus modelos, tiene sentido tener modelos separados para cada "objeto" (grupo de información relacionada). En este caso, los objetos obvios son libros, instancias de libros y autores.

+ +

También es posible que desee utilizar modelos para representar las opciones de la lista de selección (por ejemplo, como una lista desplegable de opciones), en lugar de codificar las opciones en el sitio web en sí; esto se recomienda cuando no se conocen de antemano todas las opciones posibles o éstas están sujetas a cambios. Los candidatos obvios para las modelos, en este caso, incluyen el género del libro (por ejemplo, ciencia ficción, poesía francesa, etc.) y el idioma (inglés, francés, japonés).

+ +

Una vez que hayamos decidido cuáles serán nuestros modelos y sus campos, debemos pensar en la relación que existe entre ellos. Django le permite definir relaciones de uno a uno (OneToOneField), de uno a muchos (ForeignKey) y de muchos a muchos (ManyToManyField).

+ +

Con esto en mente, el diagrama de asociación UML a continuación muestra los modelos que definiremos en este caso (como recuadros). Como se mencionó anteriormente, hemos creado modelos para el libro (los detalles genéricos del libro), instancia del libro (estado de copias físicas específicas del libro disponible en el sistema) y autor. También hemos decidido tener un modelo para el género, para que los valores se puedan crear/seleccionar a través de la interfaz admin. Hemos decidido no tener un modelo para el BookInstance:status, en su lugar, hemos especificado directamente, en el código, los valores (LOAN_STATUS) porque no esperamos que cambien. Dentro de cada uno de los cuadros, puede ver el nombre del modelo, los nombres y tipos de campo, y también los métodos y sus tipos de devolución.

+ +

El diagrama también muestra las relaciones entre los modelos, incluida su cardinalidad. La cardinalidad expresa la cantidad de instancias (máximo y mínimo) de cada modelo que pueden estar presentes en la relación. Por ejemplo, la línea de conexión entre los cuadros muestra que BookGenre están relacionados. Los números cercanos al modelo Book muestran que un libro debe tener uno o más Genres (tantos como desee), mientras que los números al otro lado de la línea al lado de Genre muestran que puede tener cero o más libros asociados.

+ +

LocalLibrary Model UML

+ +
+

Nota: La siguiente sección proporciona un manual básico que explica cómo se definen y utilizan los modelos. Mientras lo lees, considera cómo construiremos cada uno de los modelos en el diagrama de arriba.

+
+ +

Cartilla del Modelo

+ +

Esta sección provee una vista resumida de cómo se define un modelo y algunos de los campos más importantes y argumentos de campo. 

+ +

Definición de modelo

+ +

Los modelos están definidos, normalmente, en el archivo models.py de la aplicación. Son implementados como subclases de django.db.models.Model, y pueden incluir campos, métodos y metadata. El fragmento de código más abajo muestra un modelo "típico", llamado MyModelName:

+ +
from django.db import models
+
+class MyModelName(models.Model):
+    """
+    Una clase típica definiendo un modelo, derivado desde la clase Model.
+    """
+
+    # Campos
+    my_field_name = models.CharField(max_length=20, help_text="Enter field documentation")
+    ...
+
+    # Metadata
+    class Meta:
+        ordering = ["-my_field_name"]
+
+    # Métodos
+    def get_absolute_url(self):
+         """
+         Devuelve la url para acceder a una instancia particular de MyModelName.
+         """
+         return reverse('model-detail-view', args=[str(self.id)])
+
+    def __str__(self):
+        """
+        Cadena para representar el objeto MyModelName (en el sitio de Admin, etc.)
+        """
+        return self.field_name
+ +

En las secciones de abajo exploraremos cada una de las características interiores de un modelo en detalle:

+ +

Campos

+ +

Un modelo puede tener un número arbitrario de campos, de cualquier tipo. Cada uno representa una columna de datos que queremos guardar en nuestras tablas de la base de datos. Cada registro de la base de datos (fila) consistirá en uno de cada posible valor del campo. Echemos un vistazo al ejemplo visto arriba:

+ +
my_field_name = models.CharField(max_length=20, help_text="Enter field documentation")
+ +

Nuestro ejemplo de arriba tiene un único campo llamado my_field_name, de tipo models.CharField — lo que significa que este campo contendrá una cadena de caracteres alfanuméricos. Los tipos de campo son asignados usando clases específicas, que determinan el tipo de registro que se usa para guardar el dato en la base, junto con un criterio de evaluación que se usará cuando se reciban los valores de un formulario HTML (es decir, qué constituye un valor válido). Los tipos de campo pueden también tomar argumentos que especifican además cómo se guarda o cómo se puede usar. En este caso le damos a nuestro campo dos argumentos:

+ + + +

El nombre del campo se usa para referirnos a él en consultas (queries) y plantillas (templates). Los campos también tienen una etiqueta, que puede ser especificada como argumento (verbose_name) o inferida automáticamente, a partir del nombre de variable que identifica al campo, capitalizando la primera letra y reemplazando los guiones bajos por espacios (por ejemplo my_field_name tendría la etiqueta por defecto de My field name). El orden en que los campos son declarados afectará su orden por defecto si un modelo es renderizado en un formulario (ej. en el sitio de Administración), aunque este comportamiento se puede anular.

+ +
Argumentos comunes de los campos
+ +

Los siguientes argumentos son comunes a la mayoría de los tipos de campo y pueden usarse al declararlos:

+ + + +

Hay muchas otras opciones — puedes ver la lista completa de opciones aquí.

+ +
Tipos comunes de campos
+ +

La lista siguiente describe algunos de los tipos de campo más comunmente usados. 

+ + + +

Hay muchos otros tipos de campos, incluyendo campos para diferentes tipos de números (enteros grandes, enteros pequeños, en coma flotante), boleanos, URLs, slugs, identificadores únicos, y otra información relacionada con el tiempo (duración, hora, etc..). Puedes ver la lista completa aquí.

+ +

Metadatos

+ +

Puedes declarar metadatos a nivel de modelo para tu Modelo declarando class Meta, tal como se muestra.

+ +
class Meta:
+    ordering = ["-my_field_name"]
+    ...
+ +

Una de las características más útiles de estos metadatos es controlar el orden por defecto de los registros que se devuelven cuando se consulta el tipo de modelo. Se hace especificando el orden de comprobación en una lista de nombres de campo en el atributo ordering, como se muestra arriba. La ordenación dependerá del tipo de campo (los campos de caracteres de ordenan alfabéticamente, mientras que los campos de fechas están clasificados por orden cronológico). Como se muestra arriba, se puede invertir el orden de clasificación añadiendo el símbolo (-) como prefijo del nombre del campo.

+ +

Así como ejemplo, si elegimos clasificar los libros de esta forma por defecto:

+ +
ordering = ["title", "-pubdate"]
+ +

los libros serán clasificados alfabéticamente por título, de la A al a Z, y luego por fecha de publicación dentro de cada título, desde el más reciente al más antiguo.

+ +

Otro atributo común es verbose_name, un nombre descriptivo para la clase en forma singular y plural:

+ +
verbose_name = "BetterName"
+ +

Otros atributos útiles te permiten crear y aplicar nuevos "permisos de acceso" para el modelo (los permisos por defecto se aplican automáticamente), te permiten la ordenación basado en otro campo, o declarar que la clase es "abstracta" (una clase base para la que no vas a crear registros, y que en cambio se derivará para crear otros modelos).

+ +

Muchas de las otras opciones de metadatos controlan qué base datos debe usarse para el modelo y cómo se guardan los datos (éstas son realmente útiles si necesitas mapear un modelo a una base datos existente).

+ +

La lista completa de opciones de metadatos está disponible aquí: Opciones de metadatos de Modelos (Django docs).

+ +

Metodos

+ +

Un modelo puede tener también métodos

+ +

Minimamente, en cada modelo deberías definir el método estándar de las clases de Python __str__() para devolver una cadena de texto legible por humanos para cada objeto. Esta cadena se usa para representar registros individuales en el sitio de administración (y en cualquier otro lugar donde necesites referirte a una instancia del modelo). Con frecuencia éste devolverá un título o nombre de campo del modelo.

+ +
def __str__(self):
+    return self.field_name
+ +

Otro método común a incluir en los modelos de Django es get_absolute_url(), que devuelve un URL para presentar registros individuales del modelo en el sitio web (si defines este método, Django añadirá automáticamente un botón "Ver en el sitio" en la ventana de edición del registro del modelo en el sitio de Administración). Un patrón típico para get_absolute_url() se muestra abajo.

+ +
def get_absolute_url(self):
+    """
+     Devuelve la url para acceder a una instancia particular del modelo.
+    """
+    return reverse('model-detail-view', args=[str(self.id)])
+
+ +
+

Nota: Asumiendo que usarás URLs tipo /myapplication/mymodelname/2 para presentar registros individuales para tu modelo (donde "2" es el id de un registro en particular), necesitarás crear un mapeador URL para pasar la respuesta e id a la "vista detallada del modelo (model detail view)" (que hará el trabajo requerido para presentar el registro). La función reverse() de arriba es capaz de "invertir" tu mapeador url (llamado 'model-detail-view' en el caso de arriba) para crear una URL del formato correcto.

+ +

Por supuesto para hacer este trabajo ¡tienes aún que escribir el mapeo URL, la vista y la plantilla!

+
+ +

Puedes también definir todos los métodos que te apetezca y llamarlos desde tu código o plantillas (siempre y cuando no reciban ningún parámetro).

+ +

Gestión de Modelos

+ +

Una vez que has definido tus clases de modelos puedes usarlas para crear, actualizar o borrar registros, y ejecutar consultas para obtener todos los registros o subconjuntos particulares de registros. Te mostraremos cómo hacer eso en el tutorial cuando definamos nuestras vistas, pero aquí va un breve resumen.

+ +

Creación y modificación de registros

+ +

Para crear un registro puedes definir una instancia del modelo y llamar a save().

+ +
# Creación de un nuevo registro usando el constructor del modelo.
+a_record = MyModelName(my_field_name="Instancia #1")
+
+# Guardar el objeto en la base de datos.
+a_record.save()
+
+ +
+

Nota: Si no has declarado ningún campo como primary_key, al nuevo registro se le proporcionará una automáticamente, con el nombre de campo id. Puedes consultar este campo después de guardar el registro anterior y debería tener un valor de 1.

+
+ +

Puedes acceder a los campos de este nuevo registro usando la sintaxis de puntos y cambiar los valores. Tienes que llamar a save() para almacenar los valores modificados en la base de datos.

+ +
# Accesso a los valores de los campos del modelo usando atributos Python.
+print(a_record.id) # Debería devolver 1 para el primer registro.
+print(a_record.my_field_name) # Debería imprimir 'Instancia #1'
+
+# Cambio de un registro modificando los campos llamando a save() a continuación.
+a_record.my_field_name="Nuevo Nombre de Instancia"
+a_record.save()
+ +

Búsqueda de registros

+ +

Puedes buscar registros que coincidan con un cierto criterio usando el atributo objects del modelo (proporcionado por la clase base).

+ +
+

Nota: Explicar cómo buscar registros usando un modelo y nombres de campo "abstractos" puede resultar un poco confuso. En la exposición de abajo nos referiremos a un modelo Book con campos title y genre, donde genre (género) es también un modelo con un solo campo name.

+
+ +

Podemos obtener todos los registros de un modelo como QuerySet, usando objects.all(). El QuerySet es un objeto iterable, significando que contiene un número de objetos por los que podemos iterar/hacer bucle.

+ +
all_books = Book.objects.all()
+
+ +

El método de Django filter() nos permite filtrar el QuerySet devuelto para que coincida un campo de texto o numérico con un criterio particular. Por ejemplo, para filtrar libros que contengan la palabra "wild" en el título y luego contarlos, podemos hacer lo siguiente:

+ +
wild_books = Book.objects.filter(title__contains='wild')
+number_wild_books = Book.objects.filter(title__contains='wild').count()
+
+ +

Los campos a buscar y el tipo de coincidencia son definidos en el nombre del parámetro de filtro, usando el formato: field_name__match_type (ten en cuenta el doble guión bajo entre titlecontains anterior). En el ejemplo anterior estamos filtrando title por un valor sensible a mayúsculas y minúsculas. Puedes hacer otros muchos tipos de coincidencias: icontains (no sensible a mayúsculas ni minúsculas), iexact (coincidencia exacta no sensible a mayúsculas ni minúsculas), exact (coincidencia exacta sensible a mayúsculas y minúsculas) e in, gt (mayor que), startswith, etc. Puede ver la lista completa aquí.

+ +

En algunos casos, necesitarás filtrar por un campo que define una relación uno-a-muchos con otro modelo (por ejemplo, una ForeignKey). En estos casos puedes "referenciar" a campos dentro del modelo relacionado con un doble guión bajo adicional. Así, por ejemplo, para filtrar los libros de un género específico tienes que referenciar el name a través del campo genre como se muestra más abajo:

+ +
books_containing_genre = Book.objects.filter(genre__name__icontains='fiction')  # Will match on: Fiction, Science fiction, non-fiction etc.
+
+ +
+

Nota: Puedes usar guiones bajos (__)  para navegar por tantos niveles de relaciones (ForeignKey/ManyToManyField) como quieras. Por ejemplo, un Book que tuviera diferentes "types", definidos usando una relación adicional "cover", podría tener un nombre de parámetro: type__cover__name__exact='hard'.

+
+ +

Puedes hacer muchas más cosas con las consultas, incluyendo búsquedas hacia atrás de modelos relacionados, filtros encadenados, devolver un conjunto de valores más pequeño, etc. Para más información, puedes consultar Elaborar consultas (Django Docs).

+ +

Definiendo los Modelos de LocalLybrary

+ +

En esta sección comenzaremos a definir los modelos para nuestra biblioteca. Abre models.py (en /locallibrary/catalog/). El código de más arriba importa el módulo models que contiene la clase models.Model, que servirá de base para nuestros modelos:

+ +
from django.db import models
+
+# Create your models here.
+ +

Modelo 'Genre'

+ +

Copia el código del modelo Genre que se muestra abajo y pégalo al final de tu archivo models.py. Este modelo nos servirá para almacenar información relativa a la categoría del libro (por ejemplo, si es ficción o no, si es un romancero o es un libro de historia, etc.) Como se dijo más arriba, preferimos modelar el género (Genre) como una entidad, en vez de utilizar un campo de texto o una lista de opciones, porque de esta manera es posible manejar los valores a través de nuestra base de datos, en vez de fijarlo en el código (hard-coding)

+ +
class Genre(models.Model):
+    """
+    Modelo que representa un género literario (p. ej. ciencia ficción, poesía, etc.).
+    """
+    name = models.CharField(max_length=200, help_text="Ingrese el nombre del género (p. ej. Ciencia Ficción, Poesía Francesa etc.)")
+
+    def __str__(self):
+        """
+        Cadena que representa a la instancia particular del modelo (p. ej. en el sitio de Administración)
+        """
+        return self.name
+ +

El modelo tiene un único campo (name), de tipo CharField, que usaremos para describir el género literario. Este campo tiene un tamaño máximo (max_length) de 200 caracteres y, además, posee un help_text. Al final de la clase, hemos declarado el método __str__(), que simplemente devuelve el nombre de un género definido por un registro en particular. Como no hemos definido un nombre explicativo (verbose_name) para nuestro campo, éste se establecerá en Name y se mostrará de esa manera en los formularios.

+ +

Modelo 'Book'

+ +

Copia el código del modelo Book que aparece más abajo y pégalo al final de tu archivo. El modelo Libro representa la información que se tiene sobre un libro, en sentido general, pero no sobre un libro particular que se encuentre disponible en la biblioteca. Este modelo utiliza campos de tipo CharField para representar el título (title) y el isbn del libro (nota que el campo isbn especifica su etiqueta como "ISBN" utilizando el primer parámetro posicional, ya que la etiqueta por defecto hubiera sido "Isbn"). Además tenemos un campo para la sinopsis (summary), de tipo TextField, ya que este texto podría ser bastante largo.

+ +
from django.urls import reverse #Used to generate URLs by reversing the URL patterns
+
+class Book(models.Model):
+    """
+    Modelo que representa un libro (pero no un Ejemplar específico).
+    """
+
+    title = models.CharField(max_length=200)
+
+    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
+    # ForeignKey, ya que un libro tiene un solo autor, pero el mismo autor puede haber escrito muchos libros.
+    # 'Author' es un string, en vez de un objeto, porque la clase Author aún no ha sido declarada.
+
+    summary = models.TextField(max_length=1000, help_text="Ingrese una breve descripción del libro")
+
+    isbn = models.CharField('ISBN',max_length=13, help_text='13 Caracteres <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
+
+    genre = models.ManyToManyField(Genre, help_text="Seleccione un genero para este libro")
+    # ManyToManyField, porque un género puede contener muchos libros y un libro puede cubrir varios géneros.
+    # La clase Genre ya ha sido definida, entonces podemos especificar el objeto arriba.
+
+    def __str__(self):
+        """
+        String que representa al objeto Book
+        """
+        return self.title
+
+
+    def get_absolute_url(self):
+        """
+        Devuelve el URL a una instancia particular de Book
+        """
+        return reverse('book-detail', args=[str(self.id)])
+
+ +

El género es un campo de tipo ManyToManyField, de manera tal que un mismo libro podrá abarcar varios géneros y un mismo género podrá abarcar muchos libros. El autor es declarado como ForeignKey, de modo que cada libro podrá tener un sólo autor, pero un autor podrá tener muchos libros (en la vida real, un mismo libro puede tener varios autores, pero en nuestra implementación no).

+ +

En la declaración de ambos campos, el modelo relacionado se ingresa como primer parámetro posicional, usando el nombre la clase que lo implementa o, bien, el nombre del modelo como string, si éste no ha sido implementado en el archivo, antes de la declaración del campo. Otros parámetros interesantes que podemos observar, en el campo author, son null=True, que permite a la base de datos almacenar null si el autor no ha sido seleccionado, y on_delete=models.SET_NULL, que pondrá en null el campo si el registro del autor relacionado es eliminado de la base de datos.

+ +

El modelo también define __str__(), usando el campo title para representar un registro de la clase Book. El último método, get_absoulte_url() devuelve un URL que puede ser usado para acceder al detalle de un registro particular (para que esto funcione, debemos definir un mapeo de URL que tenga el nombre book-detail y una vista y una plantilla asociadas a él)

+ +

Modelo 'BookInstance'

+ +

A continuación, copie el model BookInstance  (mostrado a continuación) debajo de los otros modelos. BookInstance representa una copia específica de un libro que alguien pueda pedir prestado, en incluye información sobre si la copia esta disponible o sobre cual es la fecha que se espera sea devuelto, "imprenta" o detalles de versión, y un id único para el libro en la biblioteca.

+ +

Algunos de los campos y métodos ahora serán familiares. El modelo usa

+ + + +
import uuid # Requerida para las instancias de libros únicos
+
+class BookInstance(models.Model):
+    """
+    Modelo que representa una copia específica de un libro (i.e. que puede ser prestado por la biblioteca).
+    """
+    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="ID único para este libro particular en toda la biblioteca")
+    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
+    imprint = models.CharField(max_length=200)
+    due_back = models.DateField(null=True, blank=True)
+
+    LOAN_STATUS = (
+        ('m', 'Maintenance'),
+        ('o', 'On loan'),
+        ('a', 'Available'),
+        ('r', 'Reserved'),
+    )
+
+    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True, default='m', help_text='Disponibilidad del libro')
+
+    class Meta:
+        ordering = ["due_back"]
+
+
+    def __str__(self):
+        """
+        String para representar el Objeto del Modelo
+        """
+        return '%s (%s)' % (self.id,self.book.title)
+ +

Adicionalmente hemos declarado algunos tipos nuevos de campos:

+ + + +

El patrón __str__() representa el objeto BookInstance usando una combinación de  su id único y el título del  Book asociado.

+ +
+

Note: Un poco de Python:

+ + +
+ +

Modelo 'Author'

+ +

Copia el modelo Author  (mostrado abajo) bajo el código existente en models.py.

+ +

Todos los campos/métodos ahora deben ser familiares. El modelo define a un autor que tiene un primer nombre, apellido, fecha de nacimiento, y (opcional) fecha de fallecimiento. Especifica que de forma predeterminada el  __str__() retorna el nombre   en  el orden apellido, primer nombre. El método get_absolute_url() invierte el mapeo URL author-detail para obtener el URL para mostrar un autor individual.

+ +
class Author(models.Model):
+    """
+    Modelo que representa un autor
+    """
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        """
+        Retorna la url para acceder a una instancia particular de un autor.
+        """
+        return reverse('author-detail', args=[str(self.id)])
+
+
+    def __str__(self):
+        """
+        String para representar el Objeto Modelo
+        """
+        return '%s, %s' % (self.last_name, self.first_name)
+
+ +

Reiniciar las migraciones a la base de datos

+ +

Todos tus modelos han sido creados. Para añadirlos a tu base de datos, vuelve a ejecutar las migraciones de tu base de datos.

+ +
python3 manage.py makemigrations
+python3 manage.py migrate
+ +

Modelo 'Language' - desafío

+ +

Imagina que un benefactor local dona un número de libros nuevos escritos en otro lenguaje (digamos, Farsi). El desafío es averiguar como estos pueden ser bien representados en tu sitio Web, y luego agregarlos a los modelos.

+ +

Algunas cosas a considerar:

+ + + +

Después que hayas decidido, agrega el campo. Puedes ver que decidimos nostros en Github aquí.

+ +

No olvides que después de un cambio en tu modelo, debes volver a hacer las migraciones para que se apliquen los cambios en tu base de datos.

+ +
python3 manage.py makemigrations
+python3 manage.py migrate
+ + + + + +

Resumen

+ +

En este artículo hemos aprendido como son definidos los modelos, y luego usar esta información para diseñar e implementar modelos apropiados para el sitio Web  LocalLibrary.

+ +

En este punto nos desviaremos brevemente de la creación del sitio, y miraremos el sitio de Administración de Django. Este sitio nos permitirá añadir algunos datos a la biblioteca, los cuales podemos mostrar usando nuestras (aún por crear) vistas y plantillas.

+ +

Vea también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}

+ +

En este modulo

+ + diff --git a/files/es/learn/server-side/django/sessions/index.html b/files/es/learn/server-side/django/sessions/index.html new file mode 100644 index 0000000000..f5b751c115 --- /dev/null +++ b/files/es/learn/server-side/django/sessions/index.html @@ -0,0 +1,200 @@ +--- +title: 'Tutorial de Django Parte 7: Framework de sesiones' +slug: Learn/Server-side/Django/Sessions +tags: + - Artículo + - Principiante + - Python + - Servidor + - Sesion + - Sesiones + - Tutorial + - aprende + - django + - lado-servidor +translation_of: Learn/Server-side/Django/Sessions +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/authentication", "Learn/Server-side/Django")}}
+ +

Este tutorial extiende nuestro sitio web de la BibliotecaLocal, añadiendo un contador de visitas a tu página de inicio basado en sesiones. Es un ejemplo relativamente simple, pero muestra cómo puedes usar el framework de sesión para proporcionar persistencia a usuarios anónimos en tus propios sitios.

+ + + + + + + + + + + + +
Prerequisitos:Completar todos los tópicos anteriores del tutorial, incluyendo Django Tutorial Part 6: Generic list and detail views
Objetivo:Entender como emplear las sesiones.
+ +

Resumen

+ +

El sitio web de la BibliotecaLocal que creamos en los tutoriales previos permite a los usuarios explorar los libros y autores en el catálogo. Mientras que el contenido se genera dinámicamente desde la base de datos, todos los usuarios básicamente tendrán acceso a las mismas páginas y tipos de información cuando usan el sitio.

+ +

En una biblioteca "real" podrías querer dar a cada usuario individual una experiencia personalizada, basada en su uso previo del sitio, preferencias, etc. Por ejemplo, podrías ocultar los mensajes de advertencia que el usuario ya ha aceptado previamente la próxima vez que visite el sitio, o guardar y respetar sus preferencias (ej. el número de resultados de búsqueda que quiere desplegar en cada página).

+ +

El framework de sesiones te permite implementar este tipo de comportamiento, pudiendo guardar y recuperar información arbitraria en base a cada visitante particular del sitio.

+ +

¿Qué son las sesiones?

+ +

Toda comunicación entre los navegadores web y los servidores se da a través del protocolo HTTP, que es sin estado. El hecho de que el protocolo sea sin estado significa que los mensajes entre el cliente y el servidor son completamente independientes entre sí -- no existe una noción de "secuencia" o comportamiento basado en mensajes previos. Como resultado, si quieres tener un sitio que guarde registro de la relación que tiene lugar con un cliente, necesitas implementarlo tú mismo.

+ +

Las sesiones son el mecanismo que usa Django (y la mayor parte de Internet) para guardar registro del "estado" entre el sitio y un navegador en particular. Las sesiones te permiten almacenar información arbitraria por navegador, y tener esta información disponible para el sitio cuando el navegador se conecta. Cada pieza individual de información asociada con una sesión se conoce como "clave", que se usa tanto para guardar como para recuperar la información.

+ +

Django usa una cookie que contiene un id de sesión específica para identificar cada navegador y su sesión asociada con el sitio. La información real de la sesión se guarda por defecto en la base de datos del sitio (esto es más seguro que guardar la información en una cookie, donde es más vulnerable para los usuarios maliciosos). Puedes configurar Django para guardar la información de sesión en otros lugares (caché, archivos, cookies "seguras"), pero la opción por defecto es una buena opción y relativamente segura.

+ +

Habilitando las sesiones

+ +

Las sesiones fueron automáticamente habilitadas cuando creamos el sitio web esqueleto (en el tutorial 2).

+ +

La configuración está establecida en las secciones INSTALLED_APPS y MIDDLEWARE del archivo del proyecto (locallibrary/locallibrary/settings.py), como se muestra abajo:

+ +
INSTALLED_APPS = [
+    ...
+    'django.contrib.sessions',
+    ....
+
+MIDDLEWARE = [
+    ...
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    ....
+ +

Usando las sesiones

+ +

Puedes usar el atributo session en la vista desde el parámetro request (una HttpRequest que se envía como el primer argumento a la vista). Este atributo de sesión representa la conección específica con el usuario actual (o para ser más preciso, la conección con el navegador actual, como se identifica mediante la id de sesión en la cookie del navegador para este sitio).

+ +

El atributo session es un objeto tipo diccionario que puedes leer y escribir tantas veces como quieras en tu vista, modificándolo como desees. Puedes realizar todas las operaciones normales de diccionario, incluyendo eliminar toda la información, probar si una clave está presente, iterar a través de la información, etc. Sin embargo, la mayor parte del tiempo solo usarás la API estándar de "diccionario" para recuperar y establecer valores.

+ +

Los fragmentos de código de abajo te muestran cómo puedes recuperar, establecer o eliminar información con la clave "my_car", asociada con la sesión actual (del navegador).

+ +
+

Nota: Una de las cosas grandiosas de Django es que no necesitas pensar sobre los mecanismos que relacionan la sesión con tu solicitud actual en tu vista. Si fuéramos a usar los fragmentos de abajo en nuestra vista, sabríamos que la información sobre my_car está asociada solo con el navegador que envió la solicitud.

+
+ +
# Obtener un dato de la sesión por su clave (ej. 'my_car'), generando un KeyError si la clave no existe
+my_car = request.session['my_car']
+
+# Obtener un dato de la sesión, estableciendo un valor por defecto ('mini') si el dato requerido no existe
+my_car = request.session.get('my_car', 'mini')
+
+# Asignar un dato a la sesión
+request.session['my_car'] = 'mini'
+
+# Eliminar un dato de la sesión
+del request.session['my_car']
+
+ +

La API ofrece también una cantidad de métodos adicionales que se usan mayoritariamente para administrar la cookie de sesión asociada. Por ejemplo, hay métodos para probar si el navegador cliente soporta cookies, establecer y revisar las fechas de expiración de las cookies, y para eliminar sesiones expiradas del almacén de datos. Puedes encontrar información sobre la API completa en Cómo usar sesiones (Django docs).

+ +

Guardando la información de la sesión

+ +

Por defecto, Django solo guarda información en la base de datos de sesión y envía la cookie de sesión al cliente cuando la sesión ha sido modificada (asignada) o eliminada. Si estás actualizando algún dato usando su clave de sesión como se mostró en la sección previa, ¡no necesitas preocuparte por esto! Por ejemplo:

+ +
# Esto es detectado como un cambio en la sesión, así que la información de la sesión es guardada.
+request.session['my_car'] = 'mini'
+ +

Si estás actualizando algún dato dentro de la información de sesión, Django no reconocerá que has hecho un cambio en la sesión y guardado la información (por ejemplo, si fueras a cambiar el dato "wheels" dentro de tu dato "my_car", como se muestra abajo). En este caso, necesitarás marcar explícitamente la sesión como que ha sido modificada.

+ +
# Objeto de sesión no directamente modificada, solo información dentro de la sesión.
+# ¡Cambios no guardados!
+request.session['my_car']['wheels'] = 'alloy'
+
+# Establecer la sesión como modificada para forzar a que se guarden los cambios.
+request.session.modified = True
+
+ +
+

Nota: Puedes cambiar el comportamiento para que el sitio actualice la base de datos y envíe la cookie en cada solicitud añádiendo SESSION_SAVE_EVERY_REQUEST = True a la configuración de tu proyecto (locallibrary/locallibrary/settings.py).

+
+ +

Ejemplo simple -- obteniendo conteos de visitas

+ +

Como un ejemplo simple del mundo real, actualizaremos nuestra biblioteca para decirle al usuario actual cuántas veces ha visitado la página principal de BibliotecaLocal.

+ +

Abre /locallibrary/catalog/views.py, y aplica los cambios que se muestran con negrita abajo.

+ +
def index(request):
+    ...
+
+    num_authors=Author.objects.count()  # El 'all()' se obvia en este caso.
+
+    # Numero de visitas a esta view, como está contado en la variable de sesión.
+    num_visits = request.session.get('num_visits', 0)
+    request.session['num_visits'] = num_visits + 1
+
+    context = {
+        'num_books':num_books,
+        'num_instances':num_instances,
+        'num_instances_available':num_instances_available,
+        'num_authors':num_authors,
+        'num_visits':num_visits,
+    } 
+
+    # Carga la plantilla index.html con la información adicional en la variable context.
+    return render(request, 'index.html', context=context)
+ +

Aquí primero obtenemos el valor de la clave de sesión 'num_visits', estableciendo el valor a 0 si no había sido establecido previamente. Cada vez que se recibe la solicitud, incrementamos el valor y lo guardamos de vuelta en la sesión (para la siguiente vez que el usuario visita la página). La variable num_visits se envía entonces a la plantilla en nuestra variable de contexto.

+ +
+

Nota: Aquí podríamos incluso revisar si el navegador soporta cookies (mira Cómo usar sesiones para ejemplos) o diseñar nuestra UI de modo que no importe si el navegador soporta cookies o no.

+
+ +

Añade la línea que se ve al final del siguiente bloque a tu plantilla HTML principal (/locallibrary/catalog/templates/index.html) al final de la sección "Dynamic content" para desplegar la variable de contexto:

+ +
<h2>Dynamic content</h2>
+
+<p>The library has the following record counts:</p>
+<ul>
+  <li><strong>Books:</strong> \{{ num_books }}</li>
+  <li><strong>Copies:</strong> \{{ num_instances }}</li>
+  <li><strong>Copies available:</strong> \{{ num_instances_available }}</li>
+  <li><strong>Authors:</strong> \{{ num_authors }}</li>
+</ul>
+
+<p>You have visited this page \{{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.</p>
+
+ +

Guarda tus cambios y reinicia el servidor de pruebas. Cada vez que refresques la página, el número se debería actualizar.

+ + + +

Resumen

+ +

Ahora sabes lo fácil que es usar sesiones para mejorar tu interacción con usuarios anónimos.

+ +

En nuestros siguientes artículos explicaremos el framework de autenticación y autorización (permisos), y te mostraremos cómo soportar cuentas de usuario.

+ +

Mira también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django/Authentication", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/skeleton_website/index.html b/files/es/learn/server-side/django/skeleton_website/index.html new file mode 100644 index 0000000000..96c8b0d3b0 --- /dev/null +++ b/files/es/learn/server-side/django/skeleton_website/index.html @@ -0,0 +1,397 @@ +--- +title: 'Tutorial Django Parte 2: Creación del esqueleto del sitio web' +slug: Learn/Server-side/Django/skeleton_website +tags: + - Aprendizaje + - Artículo + - Codificación de scripts + - Guía + - Principiante + - Tutorial + - django + - introducción + - lado servidor +translation_of: Learn/Server-side/Django/skeleton_website +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}
+ +

Este segundo artículo de nuestro Tutorial Django muestra cómo puedes crear un proyecto de "esqueleto" de sitio web como base, que puedes continuar luego llenado de configuraciones específicas del sitio, urls, modelos, vistas y plantillas.

+ + + + + + + + + + + + +
Pre-requisitos:Poner en marcha un entorno de desarrollo Django. Repasar el Tutorial Django.
Objetivo: +

Ser capaz de usar las herramientas de Django para empezar tus propios proyectos de sitios web nuevos.

+
+ +

Visión general

+ +

Este artículo muestra como puedes crear un sitio web "esqueleto", que puedes luego llenar con configuraciones específicas del sitio, urls, modelos, vistas y plantillas (trataremos ésto en artículos posteriores).

+ +

El proceso es sencillo:

+ +
    +
  1. Usar la herramienta django-admin para crear la carpeta del proyecto, los ficheros de plantillas básicos y el script de gestión del proyecto  (manage.py).
  2. +
  3. Usar manage.py para crear una o más aplicaciones. +
    +

    Nota: Un sitio web puede consistir de una o más secciones, ej. sitio principal, blog, wiki, area de descargas, etc. Django te recomienda encarecidamente que desarrolles estos componentes como aplicaciones separadas que podrían ser reutilizadas, si se desea, en otros proyectos. 

    +
    +
  4. +
  5. Registrar las nuevas aplicaciones para incluirlas en el proyecto.
  6. +
  7. Conectar el mapeador url de cada aplicación.
  8. +
+ +

Para el sitio web de la BibliotecaLocal la carpeta del sitio y la carpeta de su proyecto se llamarán locallibrary, y tendremos sólo una aplicación llamada catalog. El nivel más alto de la estructura de carpetas quedará por tanto como sigue:

+ +
locallibrary/         # Carpeta del sitio webmanage.py         # Script para ejecutar las herramientas de Django para este proyecto (creadas usando django-admin)
+    locallibrary/     # Carpeta del Sitio web/Proyecto (creada usando django-admin)
+    catalog/          # Carpeta de la Aplicación (creada usando manage.py)
+
+ +

Las siguientes secciones abordan los pasos del proceso en detalle, y muestran cómo puedes comprobar los cambios. Al final de cada artículo trataremos alguna de los otros ajustes aplicables al sitio entero que deberías también efectuar en esta etapa.

+ +

Creación del proyecto

+ +

En primer lugar abre una ventana de comandos/terminal, navega hasta donde quieres almacenar tus apps Django (hazlo en algún lugar que sea fácil de encontrar, como dentro de la carpeta de tus documentos), y crea una carpeta para tu nuevo sitio web (en este caso : locallibrary). Entra en el directorio a continuación usando el comando cd:

+ +
mkdir locallibrary
+cd locallibrary
+ +

Crear el nuevo proyecto usando el comando django-admin startproject como se muestra, y navega luego dentro de la carpeta.

+ +
django-admin startproject locallibrary .
+cd locallibrary
+ +

La herramienta django-admin crea una estructura de carpetas/ficheros como se muestra abajo:

+ +
locallibrary/manage.pylocallibrary/
+        settings.py
+        urls.py
+        wsgi.py
+ +

La subcarpeta del proyecto locallibrary es el punto de entrada al sitio web: 

+ + + +

El script manage.py se usa para crear aplicaciones, trabajar con bases de datos y empezar el desarrollo del servidor web.

+ +

Creación de la aplicación catalog

+ +

A continuación, ejecuta el siguiente comando para crear la aplicación catalog que vivirá dentro de nuestro proyecto locallibrary (éste debe ejecutarse en la misma carpeta que el manage.py de tu proyecto):

+ +
python3 manage.py startapp catalog
+ +
+

Nota: el comando de arriba es para Linux/Mac OS X. En Windows el comando debería ser: py -3 manage.py startapp catalog

+ +

Si estás trabajando en Windows, reemplaza python3 por py -3 a lo largo de este módulo o simplemente python: python manage.py startapp catalog.

+
+ +

La herramienta crea una nueva carpeta y la rellena con ficheros para las diferentes partes de la aplicación (mostradas en negrilla abajo). La mayoría de los ficheros se nombran de acuerdo a su propósito, para que sea má útil (ej. las vistas se deberán guardar en views.py, los Modelos en models.py, las pruebas en tests.py, la configuración del sitio de administración en admin.py, el registro de aplicaciones en apps.py) y contienen algo de código base mínimo para trabajar con los objetos asociados.

+ +

El directorio actualizado del proyecto debería tener ahora el aspecto siguiente:

+ +
locallibrary/
+    manage.py
+    locallibrary/
+    catalog/
+        admin.py
+        apps.py
+        models.py
+        tests.py
+        views.py
+        __init__.py
+        migrations/
+
+ +

Además ahora tenemos:

+ + + +
+

Nota: ¿Te has dado cuenta qué es lo que falta en la lista de ficheros de arriba? Si bien hay un lugar para que coloques tus vistas y modelos, no hay nada para que pongas los mapeos url, las plantillas  y los ficheros estáticos. Te mostraremos cómo crearlos más adelante (éstos no se necesitan en todos los sitios web pero se necesitan en este ejemplo).

+
+ +

Registro de la aplicación catalog

+ +

Ahora que se ha creado la aplicación tenemos que registrarla en el proyecto de manera que sea incluida cuando cualquiera de las herramientas se ejecute (por ejemplo, para añadir modelos a la base de datos). Las aplicaciones se registran añadiéndolas a la lista de INSTALLED_APPS en los ajustes del proyecto.

+ +

Abre el fichero de ajustes del proyecto locallibrary/locallibrary/settings.py y encuentra la definición de la lista INSTALLED_APPS. Añade a continuación una nueva linea al final de la lista, como se muestra en negrilla abajo.

+ +
INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'catalog.apps.CatalogConfig', 
+]
+ +

La nueva linea especifica el objeto de configuración de la aplicación (CatalogConfig) que se generó para tí en /locallibrary/catalog/apps.py cuando creaste la aplicación.

+ +
+

Nota: Te habrás fijado que hay ya un montón de otras INSTALLED_APPS (y MIDDLEWARE, más abajo en el fichero de ajustes). Éstas habilitan en soporte para el Sitio de admistración Django y como consecuencia el motón de la funcionalidad que usa (incluyendo sesiones, autenticación, etc).

+
+ +

Especificación de la base de datos

+ +

Éste es también el punto donde normalmente especificarías la base de datos a utilizar en el proyecto — tiene sentido usar la misma base datos para desarrollo y producción donde sea posible, para evitar diferencias menores en el comportamiento. Puedes encontrar información sobre las diferentes opciones de bases de datos en Databases (Django docs). 

+ +

Nosotros usaremos la base de datos SQLite para este ejemplo, porque no esperamos que se requiera un montón de accesos concurrentes en una base de datos de demostración, y también ¡porque no requiere trabajo adicional para ponerla en marcha! Puedes ver cómo está configurada en settings.py (más información también se incluye abajo):

+ +
DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+ +

Debido a que usamos SQLite, no necesitamos hacer ningún ajuste adicional aquí. ¡Sigamos!

+ +

Otros ajustes del proyecto

+ +

El fichero settings.py se usa para configurar muchos otros ajustes, pero en este punto probablemente sólo querrás cambiar la TIME_ZONE — ésta debería ser igual a una cadena de la Lista de base de datos tz de time zones (la columna TZ column de la tabla contiene los valores que quieres). Cambia tu TIME_ZONE al valor de entre estas cadenas que sea apropiado para tu zona de tiempo, por ejemplo:

+ +
TIME_ZONE = 'Europe/Madrid'
+ +

Hay otros dos otros ajustes que no cambiarás ahora, pero de los que deberías ser consciente:

+ + + +

Conectar el mapeador URL

+ +

El sitio web se crea con un fichero mapeador de URLs (urls.py) en la carpeta del proyecto. Aunque puedes usar este fichero para gestionar todos tus mapeos URL, es más usual deferir los mapeos a su aplicación asociada.

+ +

Abre locallibrary/locallibrary/urls.py y fíjate en el texto educativo que explica algunas formas de usar el mapeador URL. 

+ +
"""locallibrary URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/2.0/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+]
+
+ +

Los mapeos URL se gestionan a través de la variable urlpatterns, que es una lista Python de funciones path(). Cada función path() o asocia un patrón URL a una vista específica, que se presentará cuando el patrón se empareja o con otra lista de código de comprobación de patrones URL (en este segundo caso, los patrones se convierten en la "URL base" de patrones definidos en el módulo destino). La lista urlpatterns define inicialmente una función que mapea todos los URLs con el patrón admin/ al módulo admin.site.urls , que contiene las definiciones de mapeos URL propios de la aplicación de Administración.

+ +
+

Nota: La ruta en path() es una cadena que define un patrón URL para emparejar. Esta cadena podría incluir una variable nombrada (entre paréntesis angulares), ej. 'catalog/<id>/'. Este patrón emparejará con una URL como /catalog/any_chars/ y pasará a la vista any_chars como cadena asociada al parámetro de nombre id). Trataremos de los métodos de caminos y rutas de patrones más adelante en los últimos temas.

+
+ +

Añade las lineas de abajo al final del fichero para añadir un nuevo elemento a la lista urlpatterns. Este nuevo elemento incluye un path() que redirige las peticiones con el patrón catalog/ al módulocatalog.urls (el fichero con el URL relativo /catalog/urls.py).

+ +
# Use include() to add paths from the catalog application
+from django.urls import include
+
+urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+
+ +

Ahora redirijamos la URL raíz de nuestro sitio (ej. 127.0.0.1:8000) al URL 127.0.0.1:8000/catalog/; esta es la única app que usaremos en este proyecto, así que es lo que deberíamos hacer. Para hacer esto, usaremos una función especial (RedirectView), que toma como su primer argumento la nueva URL relativa a redirigir a (/catalog/) cuando el patrón URL especificado en la función path() se empareja (la URL raíz, en este caso).

+ +

Añade las siguientes líneas, otra vez al final del fichero:

+ +
#Add URL maps to redirect the base URL to our application
+from django.views.generic import RedirectView
+urlpatterns += [
+    path('', RedirectView.as_view(url='/catalog/', permanent=True)),
+]
+ + + +

Deja el primer parámetro de la función path vacío, para implicar '/'. Si escribes el primer parámetro como '/' Django te dará la siguiente advertencia cuando arranque el servidor de desarrollo:

+ +

La comprobación del sistema encontró algunos problemas:

+ +
WARNINGS:
+?: (urls.W002) Tu patrón URL '/' tiene una ruta que empieza con una '/'.
+Quita esta barra invertida ya que es inncesaria.
+Si este patrón figura como destino en un include(), asegúrate que el patrón include() tiene un '/' final.
+ + + +

Django no sirve ficheros estáticos como CSS, JavaScript e imágenes por defecto, pero puede ser útil para el servidor web de desarrollo hacerlo así mientras creas tu sitio. Como adición final a este mapeador URL, puedes habilitar el servicio de ficheros estáticos durante el desarrollo añadiendo las líneas siguientes.

+ +

Añade ahora el siguiente bloque final al final del fichero:

+ +
# Use static() to add url mapping to serve static files during development (only)
+from django.conf import settings
+from django.conf.urls.static import static
+
+urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+
+ +
+

Nota: Hay numerosas formas de extender la lista urlpatterns (arriba hemos añadido simplemente un nuevo elemento a la lista usando el operador += para separar claramente el código antiguo y el nuevo). En vez de ello podríamos haber simplemente incluido este nuevo patrón de mapeo en la definición de la lista original:

+ +
urlpatterns = [
+    path('admin/', admin.site.urls),
+    path('catalog/', include('catalog.urls')),
+    path('/', RedirectView.as_view(url='/catalog/', permanent=True)),
+] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+
+ +

Además, hemos incluido la linea import (from django.urls import include) con el código que la usa (de manera que sea fácil ver qué hemos añadido), pero es común incluir todas tus líneas import al principio del fichero Python.

+
+ +

Como paso final, crea un fichero dentro de tu carpeta catalog llamado urls.py, y añade el siguiente texto para definir la urlpatterns importada (vacía). Éste es donde añadimos nuestros patrones a medida que construimos la aplicación. 

+ +
from django.conf.urls import url
+
+from . import views
+
+
+urlpatterns = [
+
+]
+
+ +

Prueba del framework del sitio web

+ +

En este punto tenemos un proyecto de esqueleto completo. El sitio web no hace realmente nada todavía, pero merece la pena ejecutarlo para estar seguros de que ninguno de nuestros cambios no han roto nada.

+ +

Antes de hacerlo, deberíamos primero ejecutar una migración de la base de datos. Ésto actualiza nuestra base de datos para incluir todos los modelos de nuestras aplicaciones instaladas (y eliminar algunas advertencias de construcción).

+ +

Ejecución de migraciones de la base de datos

+ +

Django usa un Object-Relational-Mapper (ORM) para mapear las definiciones de Modelos en el código Django con la estructura de datos utilizada por la base de datos subyacente. A medida que cambiamos nuestras definiciones de modelos, Django sigue la pista a los cambios y puede crear scripts de migración de la base de datos (en /locallibrary/catalog/migrations/) para migrar automáticamente la estructura de datos subyacente en el base de datos para igualarse al modelo.

+ +

Cuando creamos el sitio web de Django añadimos automáticamente unos cuantos modelos para que ser usados por la sección de administración del sitio (al que echaremos un vistazo más tarde). Ejecuta los siguientes comandos para definir tablas para esos modelos de la base (asegúrate que estás en el directorio que contiene manage.py):

+ +
python3 manage.py makemigrations
+python3 manage.py migrate
+
+ +
+

Importante: Necesitarás ejecutar los comandos de arriba cada vez que cambien tus modelos de una manera que afecte a la estructura de datos y necesite ser guardada (incluyendo tanto la adicción como la eliminación de modelos enteros o campos individuales).

+
+ +

El comando makemigrations crea (pero no aplica) las migraciones para todas las aplicaciones instaladas en tu proyecto (también puedes especificar el nombre de una aplicación para ejecutar una migración para un sólo proyecto). Ésto te da la opoortunidad de comprobar el código para estas migraciones antes de que se apliquen — cuando seas un experto en Django ¡podrás elegir modificarlos ligeramente!

+ +

El comando migrate aplica realmente las migraciones a tu base de datos (Django lleva la cuenta de cuáles han sido añadidas a la base de datos actual).

+ +
+

Nota: Mira en Migrations (Django docs) para obtener información adicional sobre los comandos de migración menos usados.

+
+ +

Arrancando el sitio web

+ +

Durante el desarrollo puedes probar el sitio web usando para servirlo el servidor de desarrollo web, y visualizádolo en tu explorador web local. 

+ +
+

Nota: el servidor web de desarrollo no es robusto y sin suficientes prestaciones para su uso en producción, pero es una manera muy fácil de tener levantado y funcionando tu sitio web Django durante el desarrollo para hacerle una prueba rápida y conveniente. Por defecto servirá el sitio a tu computadora local (http://127.0.0.1:8000/), pero puedes también especificar que se sirva a otras computdoras en tu red. Para más información ver django-admin y manage.py: runserver (Django docs).

+
+ +

Ejecuta el servidor web de desarrollo llamando al comando runserver (en el mismo directorio donde está manage.py):

+ +
python3 manage.py runserver
+
+ Performing system checks...
+
+ System check identified no issues (0 silenced).
+ September 22, 2016 - 16:11:26
+ Django version 1.10, using settings 'locallibrary.settings'
+ Starting development server at http://127.0.0.1:8000/
+ Quit the server with CTRL-BREAK.
+
+ +

Una vez que el servidor está funcionando puedes ver el sitio navegando a http://127.0.0.1:8000/ en tu explorador local. Deberías ver una página de error del sitio que tiene el siguiente aspecto:

+ +

Django Debug page for Django 2.0

+ +

¡No te preocupes! Esta página de error es lo esperado porque no tenemos ninguna página/url definidas en el módulo catalogs.urls (que es al que nos redirigimos cuando obtenemos la URL a la raíz del sitio). 

+ +
+

Nota: La página superior demuestra una gran característica de Django— El registro de depuración automático. Cada vez que una página no pueda ser encontrada, o el código provoque un error cualquiera, se mostrará una pantalla de error con información útil. En este caso vemos que la URL que hemos suministrado no empareja con ninguno de nuestros patrones de URL (como los listados). El resgistro de depuración puede desconectarse durante la producción (cuando colocamos el sitio en vivo en la Web), en cuyo caso se servirá una página menos informativa pero más amigable.

+
+ +

¡En este punto ya sabemos que Django está funcionando!

+ +
+

Nota: Deberías volver a ejecutar las migraciones y volver a probar el sitio cada vez que hagas cambios significativos. ¡No lleva tanto tiempo!

+
+ +

Desafíate a tí mismo

+ +

El directorio catalog/ contiene ficheros para las vistas, modelos y otras partes de la aplicación. Abre estos ficheros e inspecciona el código base. 

+ +

Como has visto arriba, se ha añadido ya un mapeo de URLs para el sitio de administración en el fichero del proyecto urls.py. Navega al área de adminsitración en tu explorador y mira qué sucede (puedes inferir el URL correcto de los mapeos de arriba).

+ + + +

Sumario

+ +

ahora ya has creado un proyecto de esqueleto completo de sitio web, con el que puedes continuar rellenando con urls, modelos, vistas y plantillas.

+ +

Ahora que el esqueleto del sitio web de la BibliotecaLocal está completo y funcionando, es hora de empezar a escribir el código que hace que este sitio haga lo que se supone que debe hacer. 

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/testing/index.html b/files/es/learn/server-side/django/testing/index.html new file mode 100644 index 0000000000..54055b2780 --- /dev/null +++ b/files/es/learn/server-side/django/testing/index.html @@ -0,0 +1,906 @@ +--- +title: 'Tutorial de Django Parte 10: Probando una aplicación web Django' +slug: Learn/Server-side/Django/Testing +translation_of: Learn/Server-side/Django/Testing +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}
+ +

A medida que crecen los sitios web se vuelven más difíciles de probar a mano — no sólo hay más para probar, sino que además, a medida que las interacciones entre los componentes se vuelven más complejas, un pequeño cambio en un área puede suponer muchas pruebas adicionales para verificar su impacto en otras áreas. Una forma de mitigar estos problemas es escribir tests automatizados, que pueden ser ejecutados de manera fácil y fiable cada vez que hagas un cambio. Este tutorial muestra cómo automatizar la unidad de pruebas de tu sitio web usando el framework de pruebas de Django.

+ + + + + + + + + + + + +
Prerequisites:Completa todos los tópicos anteriores, incluyendo Tutorial Django Parte 9: Trabajando con formularios.
Objective:Entender como escribir pruebas unidatarias para django basado en Páginas web.
+ +

Vista previa

+ +

El Local Library actualmente tiene páginas para mostrar las listas con todos los libros y autores, vistas detalladas para los items de Book y Author,una página para renovar BookInstances y páginas para crear, actualizar y eliminar elementos de autor (y también registros de libros, si  usted completó el desafío en el tutorial de formularios). Incluso con este sitio relativamente pequeño, navegar manualmente a cada página y verificar superficialmente que todo funcione como se espera, puede llevar varios minutos. A medida que hagamos cambios y el sitio vaya creciendo, el tiempo requerido para verificar manualmente que todo funcione "correctamente", aumentará de forma muy perniciosa. Si continuamos como estamos, pasaríamos la mayor parte de nuestro tiempo probando, y muy poco tiempo mejorando nuestro código.

+ +

¡Las pruebas automatizadas realmente pueden ayudar con este problema! Los beneficios obvios son que pueden  ejecutarse mucho más rápido que las pruebas manuales, pueden probar con un nivel de detalle mucho más bajo y probar exactamente la misma funcionalidad cada vez (¡los testers humanos no son tan confiables!) Porque son pruebas rápidas y automatizadas se puede ejecutar más regularmente, y si falla una prueba,
+ señalan exactamente dónde el código no está funcionando como se esperaba.

+ +

Además, las pruebas automatizadas pueden actuar como el primer "usuario" del mundo real de su código, lo que le obliga a ser riguroso a la hora de definir y documentar bien, cómo debe comportarse su sitio web. A menudo son la base de sus ejemplos de código y documentación. Por estas razones, algunos procesos de desarrollo de software comienzan con la definición e implementación de la prueba, después de lo cual el código se escribe para que coincida con el comportamiento requerido (por ejemplo, desarrollo basado en pruebas y en comportamiento).
+
+ Este tutorial muestra cómo escribir pruebas automatizadas para Django, agregando una serie de pruebas al sitio web LocalLibrary.

+ +

Tipos de pruebas

+ +

Hay numeroso tipos, niveles y clasificaciones de pruebas y enfoques de pruebas. Las pruebas automáticas más importantes son:

+ +
+
Pruebas unitarias
+
Verifica el comportamiento funcional de un componente individual, a menudo de una clase y su nivel de funcional.
+
Pruebas de regresión
+
Pruebas que reproducen errores históricos. Cada prueba es inicialmente ejecutada para verificar que el error ha sido corregido, y estos son ejecutados de nuevo para asegurarnos que los errores no fueron reintroducidos con los futuros cambios en el código.
+
Pruebas de integración
+
Verifica cómo funcionan los grupos de componentes cuando se usan juntos. Las pruebas de integración son conscientes de las interacciones requeridas entre componentes, pero no necesariamente de las operaciones internas de cada componente. Pueden cubrir agrupaciones simples de componentes hasta todo el sitio web.
+
+ +
+

Nota: Otros tipos comunes de pruebas incluyen pruebas de caja negra, caja blanca, manuales, automatizadas, canarias, de humo, de conformidad, de aceptación, funcionales, de rendimiento, de carga y de esfuerzo. Búscalos para más información.

+
+ +

Que provee Django para pruebas?

+ +

Probar un sitio web es una tarea compleja, porque está compuesto por varias capas de lógica, desde el manejo de solicitudes a nivel HTTP, modelos de consultas, hasta la validación y procesamiento de formularios y la representación de plantillas.

+ +

Django proporciona un marco de prueba con una pequeña jerarquía de clases que se basan en la libreria unittest estándar Python. A pesar del nombre, este marco de prueba es adecuado tanto para pruebas unitarias como de integración. El marco de Django agrega métodos y herramientas API para ayudar a probar el comportamiento web y específico de Django. Estos le permiten simular solicitudes, insertar datos de prueba e inspeccionar la salida de su aplicación. Django también proporciona una API(LiveServerTestCase) y herramientas para  usar diferentes frameworks de pruebas , por ejemplo, puede integrarse con el popular framework Selenium para simular la interacción de un usuario con un navegador en vivo.

+ +

Para escribir una prueba, se deriva de cualquiera de las clases base de prueba de Django (o unittest)(SimpleTestCaseTransactionTestCaseTestCaseLiveServerTestCase) y luego escribir métodos separados para verificar que la funcionalidad específica funcione como se esperaba (las pruebas usan métodos "assert"  para probar que las expresiones dan valores True o False, o que dos valores son iguales, etc.) Cuando inicia una ejecución de prueba, el marco ejecuta los métodos de prueba elegidos en sus clases derivadas. Los métodos de prueba se ejecutan de forma independiente, con un comportamiento común de configuración y / o desmontaje definido en la clase, como se muestra a continuación.

+ +
class YourTestClass(TestCase):
+
+    def setUp(self):
+        #Setup run before every test method.
+        pass
+
+    def tearDown(self):
+        #Clean up run after every test method.
+        pass
+
+    def test_something_that_will_pass(self):
+        self.assertFalse(False)
+
+    def test_something_that_will_fail(self):
+        self.assertTrue(False)
+
+ +

La mejor clase base para la mayoría de las pruebas es django.test.TestCase.  Esta clase de prueba crea una base de datos limpia antes de que se ejecuten sus pruebas y ejecuta cada función de prueba en su propia transacción. La clase también posee una prueba Client que puede utilizar para simular la interacción de un usuario con el código en el nivel de vista. En las siguientes secciones, nos concentraremos en las pruebas unitarias, creadas con esta clase TestCase

+ +
+

Nota: La clase django.test.TestCase es muy conveniente, pero puede resultar en que algunas pruebas sean más lentas de lo necesario (no todas las pruebas necesitarán configurar su propia base de datos o simular la interacción de la vista). Una vez que esté familiarizado con lo que puede hacer con esta clase, es posible que desee reemplazar algunas de sus pruebas con las clases de prueba más simples disponibles.

+
+ +

Que deberias probar?

+ +

Debe probar todos los aspectos de su propio código, pero no ninguna biblioteca o funcionalidad proporcionada como parte de Python o Django.

+ +

Por ejemplo, considere el modelo Author definido abajo. No es necesario probarlo explícitamente first_name y last_name han sido almacenados correctamente como CharField en la base de datos porque eso es algo definido por Django (aunque, por supuesto, en la práctica, inevitablemente probará esta funcionalidad durante el desarrollo). Tampoco es necesario probar que el date_of_birth ha sido validado para ser un campo de fecha, porque nuevamente es algo implementado en Django.

+ +

Sin embargo, debe verificar el texto utilizado para las etiquetas (nombre, apellido, fecha de nacimiento, fallecimiento) y el tamaño del campo asignado para el texto (100 caracteres), porque estos son parte de su diseño y algo que podría ser roto / cambiado en el futuro.

+ +
class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return '%s, %s' % (self.last_name, self.first_name)
+ +

Del mismo modo, debe verificar que los métodos personalizados get_absolute_url()__str__()comportarse como sea necesario porque son su código / lógica empresarial. En el caso de get_absolute_url() puedes confiar en que el metodo de Django reverse() se ha implementado correctamente, por lo que lo que está probando es que la vista asociada se haya definido realmente.

+ +
+

Nota: Los lectores astutos pueden notar que también querríamos restringir la fecha de nacimiento y muerte a valores sensibles, y comprobar que la muerte viene después del nacimiento. En Django, esta restricción se agregaría a sus clases de formulario (aunque puede definir validadores para los campos, estos parecen usarse solo en el nivel del formulario, no en el nivel del modelo).

+
+ +

Con eso en mente, comencemos a ver cómo definir y ejecutar pruebas.

+ +

Descripción general de la estructura de prueba

+ +

Antes de entrar en los detalles de "qué probar", primero veamos brevemente dónde y cómo se definen las pruebas..

+ +

Django utiliza el descubrimiento de pruebas integrado del módulo unittest (built-in test discovery), que descubrirá pruebas en el directorio de trabajo actual en cualquier archivo nombrado con el patrón test*.py. Siempre que asigne un nombre a los archivos de forma adecuada, puede utilizar la estructura que desee. Le recomendamos que cree un módulo para su código de prueba y que tenga archivos separados para modelos, vistas, formularios y cualquier otro tipo de código que necesite probar. Por ejemplo:

+ +
catalog/
+  /tests/
+    __init__.py
+    test_models.py
+    test_forms.py
+    test_views.py
+
+ +

Cree una estructura de archivo como se muestra arriba en su proyecto  LocalLibrary. El  __init__.py debe ser un archivo vacío (esto le dice a Python que el directorio es un paquete). Puede crear los tres archivos de prueba copiando y cambiando el nombre del archivo de prueba de esqueleto /catalog/tests.py.

+ +
+

Note:El archivo de prueba /catalog/tests.pyse creó automáticamente cuando creamos el sitio web esqueleto de Django ( built the Django skeleton website).

+ +

Es perfectamente "legal" poner todas sus pruebas dentro de él, pero si prueba correctamente, rápidamente terminará con un archivo de prueba muy grande e inmanejable.

+ +

Elimina el archivo esqueleto ya que no lo necesitaremos.

+
+ +

Abre el archivo /catalog/tests/test_models.py. El archivo debe importar django.test.TestCase, como se muestra:

+ +
from django.test import TestCase
+
+# Create your tests here.
+
+ +

A menudo, agregará una clase de prueba para cada modelo / vista / formulario que desee probar, con métodos individuales para probar una funcionalidad específica. En otros casos, es posible que desee tener una clase separada para probar un caso de uso específico, con funciones de prueba individuales que prueben aspectos de ese caso de uso (por ejemplo, una clase para probar que un campo de modelo está validado correctamente, con funciones para probar cada uno de los posibles casos de falla). Una vez más, la estructura depende en gran medida de usted, pero es mejor si es coherente.

+ +

Agregue la clase de prueba a continuación al final del archivo. La clase demuestra cómo construir una clase de caso de prueba derivando de TestCase.

+ +
class YourTestClass(TestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        print("setUpTestData: Run once to set up non-modified data for all class methods.")
+        pass
+
+    def setUp(self):
+        print("setUp: Run once for every test method to setup clean data.")
+        pass
+
+    def test_false_is_false(self):
+        print("Method: test_false_is_false.")
+        self.assertFalse(False)
+
+    def test_false_is_true(self):
+        print("Method: test_false_is_true.")
+        self.assertTrue(False)
+
+    def test_one_plus_one_equals_two(self):
+        print("Method: test_one_plus_one_equals_two.")
+        self.assertEqual(1 + 1, 2)
+ +

La nueva clase define dos métodos que puede utilizar para la configuración previa a la prueba (por ejemplo, para crear modelos u otros objetos que necesitará para la prueba):

+ + + +
+

Las clases de prueba también tienen un metodo tearDown() que no hemos utilizado. Este método no es particularmente útil para las pruebas de bases de datos, ya que TestCase la clase base se encarga del desmontaje de la base de datos por usted.

+
+ +

Debajo de ellos tenemos una serie de métodos de prueba, que utilizamos funciones Assert toprobar si las condiciones son verdaderas, falsas o iguales (AssertTrue, AssertFalse, AssertEqual). Si la condición no se evalúa como se esperaba, la prueba fallará y reportará el error a su consola.

+ +

Los AssertTrue, AssertFalse, AssertEqual son afirmaciones estándar proporcionadas por unittest.  Hay otras aserciones estándar en el marco y también aserciones específicas de Django (Django-specific assertions) para probar si una vista redirecciona (assertRedirects),para probar si se ha utilizado una plantilla en particular (assertTemplateUsed), etc.

+ +
+

Normalmente no debería incluir funciones print () en sus pruebas como se muestra arriba. Lo hacemos aquí solo para que pueda ver el orden en que se llaman las funciones de configuración en la consola (en la siguiente sección).

+
+ +

Como correr las pruebas

+ +

La forma más sencilla de ejecutar todas las pruebas es utilizar el comando:

+ +
python3 manage.py test
+ +

Esto descubrirá todos los archivos nombrados con el patrón test*.py bajo el directorio actual y ejecute todas las pruebas definidas usando las clases base apropiadas (aquí tenemos una serie de archivos de prueba, pero solo /catalog/tests/test_models.py contiene actualmente cualquier prueba). De forma predeterminada, las pruebas informarán individualmente solo sobre las fallas de las pruebas, seguidas de un resumen de la prueba.

+ +
+

Si recibe errores similares a: ValueError: Missing staticfiles manifest entry ... esto puede deberse a que las pruebas no ejecutan collectstatic de forma predeterminada y su aplicación usa una clase de almacenamiento que lo requiere (consulte manifest_strict para obtener más información). Hay varias formas de superar este problema; la más fácil es simplemente ejecutar collectstatic antes de ejecutar las pruebas:

+ +
python3 manage.py collectstatic
+
+
+ +

Ejecute las pruebas en el directorio raíz de LocalLibrary. Debería ver un resultado como el siguiente.

+ +
>python manage.py test
+
+Creating test database for alias 'default'...
+setUpTestData: Run once to set up non-modified data for all class methods.
+setUp: Run once for every test method to setup clean data.
+Method: test_false_is_false.
+.setUp: Run once for every test method to setup clean data.
+Method: test_false_is_true.
+FsetUp: Run once for every test method to setup clean data.
+Method: test_one_plus_one_equals_two.
+.
+======================================================================
+FAIL: test_false_is_true (catalog.tests.tests_models.YourTestClass)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "D:\Github\django_tmp\library_w_t_2\locallibrary\catalog\tests\tests_models.py", line 22, in test_false_is_true
+    self.assertTrue(False)
+AssertionError: False is not true
+
+----------------------------------------------------------------------
+Ran 3 tests in 0.075s
+
+FAILED (failures=1)
+Destroying test database for alias 'default'...
+ +

Aquí vemos que tuvimos una falla de prueba, y podemos ver exactamente qué función falló y por qué (se espera esta falla, porque False no es True!).

+ +
+

Sugerencia: Lo más importante que debe aprender del resultado de la prueba anterior es que es mucho más valioso si usa nombres descriptivos / informativos para sus objetos y métodos.

+
+ +

El texto que se muestra en negritas anterior normalmente no aparecería en la salida de prueba (esto es generado por la funcion print() en nuestra prueba). Esto muestra el metodo setUpTestData() es llamado una vez para la clase y setUp()se llama antes de cada método.

+ +

Las siguientes secciones muestran cómo puede ejecutar pruebas específicas y cómo controlar cuánta información muestran las pruebas.

+ +

Mostrando más información de las pruebas

+ +

Si desea obtener más información sobre la ejecución de prueba, puede cambiar el nivel de detalle. Por ejemplo, para enumerar los éxitos y fallas de la prueba (y una gran cantidad de información sobre cómo está configurada la base de datos de prueba), puede establecer la verbosidad en "2" como se muestra:

+ +
python3 manage.py test --verbosity 2
+ +

The allowed verbosity levels are 0, 1, 2, and 3, with the default being "1".

+ +

Ejecutando pruebas especificas

+ +

Si desea ejecutar un subconjunto de sus pruebas, puede hacerlo especificando la ruta de puntos completa al paquete (s), módulo, TestCase subclase o metodo:

+ +
python3 manage.py test catalog.tests   # Run the specified module
+python3 manage.py test catalog.tests.test_models  # Run the specified module
+python3 manage.py test catalog.tests.test_models.YourTestClass # Run the specified class
+python3 manage.py test catalog.tests.test_models.YourTestClass.test_one_plus_one_equals_two  # Run the specified method
+
+ +

Pruebas en el proyecto LocalLibrary

+ +

Ahora que sabemos cómo ejecutar nuestras pruebas y qué tipo de cosas necesitamos probar, veamos algunos ejemplos prácticos.

+ +
+

Nota: No escribiremos todas las pruebas posibles, pero esto debería darle una idea de cómo funcionan las pruebas y qué más puede hacer.

+
+ +

Modelos

+ +

Como se discutió anteriormente, debemos probar todo lo que sea parte de nuestro diseño o que esté definido por el código que hayamos escrito, pero no las bibliotecas / código que ya haya probado Django o el equipo de desarrollo de Python.

+ +

Por ejemplo, considere el modelo de Author a continuación. Aquí deberíamos probar las etiquetas para todos los campos, porque aunque no hemos especificado explícitamente la mayoría de ellos, tenemos un diseño que dice cuáles deberían ser estos valores. Si no probamos los valores, entonces no sabemos que las etiquetas de los campos tienen sus valores deseados. De manera similar, aunque confiamos en que Django creará un campo de la longitud especificada, vale la pena especificar una prueba para esta longitud para asegurarse de que se implementó según lo planeado.

+ +
class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return '%s, %s' % (self.last_name, self.first_name)
+ +

Abra su /catalog/tests/test_models.py, y reemplace cualquier código existente con el siguiente código de prueba para el modelo de Author.

+ +

Aquí usted verá que primero importamos TestCase y derivamos nuestras clases de prueba (AuthorModelTest) de ello, usando un nombre descriptive para que así podamos fácilmente cualquier pruebas fallidas en el output de la prueba. Luego llamamos a setUpTestData() para crear un objeto de autor que usaremos pero no modificaremos en ninguna de las pruebas.

+ +
from django.test import TestCase
+
+# Create your tests here.
+
+from catalog.models import Author
+
+class AuthorModelTest(TestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        #Set up non-modified objects used by all test methods
+        Author.objects.create(first_name='Big', last_name='Bob')
+
+    def test_first_name_label(self):
+        author=Author.objects.get(id=1)
+        field_label = author._meta.get_field('first_name').verbose_name
+        self.assertEquals(field_label,'first name')
+
+    def test_date_of_death_label(self):
+        author=Author.objects.get(id=1)
+        field_label = author._meta.get_field('date_of_death').verbose_name
+        self.assertEquals(field_label,'died')
+
+    def test_first_name_max_length(self):
+        author=Author.objects.get(id=1)
+        max_length = author._meta.get_field('first_name').max_length
+        self.assertEquals(max_length,100)
+
+    def test_object_name_is_last_name_comma_first_name(self):
+        author=Author.objects.get(id=1)
+        expected_object_name = '%s, %s' % (author.last_name, author.first_name)
+        self.assertEquals(expected_object_name,str(author))
+
+    def test_get_absolute_url(self):
+        author=Author.objects.get(id=1)
+        #This will also fail if the urlconf is not defined.
+        self.assertEquals(author.get_absolute_url(),'/catalog/author/1')
+ +

The field tests check that the values of the field labels (verbose_name) and that the size of the character fields are as expected. These methods all have descriptive names, and follow the same pattern:

+ +
author=Author.objects.get(id=1)   # Get an author object to test
+field_label = author._meta.get_field('first_name').verbose_name   # Get the metadata for the required field and use it to query the required field data
+self.assertEquals(field_label,'first name')  # Compare the value to the expected result
+ +

The interesting things to note are:

+ + + +
+

Note: Tests for the last_name and date_of_birth labels, and also the test for the length of the last_name field have been omitted. Add your own versions now, following the naming conventions and approaches shown above.

+
+ +

We also need to test our custom methods. These essentially just check that the object name was constructed as we expected using "Last Name", "First Name" format, and that the URL we get for an Author item is as we would expect.

+ +
def test_object_name_is_last_name_comma_first_name(self):
+    author=Author.objects.get(id=1)
+    expected_object_name = '%s, %s' % (author.last_name, author.first_name)
+    self.assertEquals(expected_object_name,str(author))
+
+def test_get_absolute_url(self):
+    author=Author.objects.get(id=1)
+    #This will also fail if the urlconf is not defined.
+    self.assertEquals(author.get_absolute_url(),'/catalog/author/1')
+ +

Run the tests now. If you created the Author model as we described in the models tutorial it is quite likely that you will get an error for the date_of_death label as shown below. The test is failing because it was written expecting the label definition to follow Django's convention of not capitalising the first letter of the label (Django does this for you).

+ +
======================================================================
+FAIL: test_date_of_death_label (catalog.tests.test_models.AuthorModelTest)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "D:\...\locallibrary\catalog\tests\test_models.py", line 32, in test_date_of_death_label
+    self.assertEquals(field_label,'died')
+AssertionError: 'Died' != 'died'
+- Died
+? ^
++ died
+? ^
+ +

This is a very minor bug, but it does highlight how writing tests can more thoroughly check any assumptions you may have made.

+ +
+

Note: Change the label for the date_of_death field (/catalog/models.py) to "died" and re-run the tests.

+
+ +

The patterns for testing the other models are similar so we won't continue to discuss these further. Feel free to create your own tests for the our other models.

+ +

Formularios

+ +

The philosophy for testing your forms is the same as for testing your models; you need to test anything that you've coded or your design specifies, but not the behaviour of the underlying framework and other third party libraries.

+ +

Generally this means that you should test that the forms have the fields that you want, and that these are displayed with appropriate labels and help text. You don't need to verify that Django validates the field type correctly (unless you created your own custom field and validation) — i.e. you don't need to test that an email field only accepts emails. However you would need to test any additional validation that you expect to be performed on the fields and any messages that your code will generate for errors.

+ +

Consider our form for renewing books. This has just one field for the renewal date, which will have a label and help text that we will need to verify.

+ +
class RenewBookForm(forms.Form):
+    """
+    Form for a librarian to renew books.
+    """
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+    def clean_renewal_date(self):
+        data = self.cleaned_data['renewal_date']
+
+        #Check date is not in past.
+        if data < datetime.date.today():
+            raise ValidationError(_('Invalid date - renewal in past'))
+        #Check date is in range librarian allowed to change (+4 weeks)
+        if data > datetime.date.today() + datetime.timedelta(weeks=4):
+            raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+        # Remember to always return the cleaned data.
+        return data
+ +

Open our /catalog/tests/test_forms.py file and replace any existing code with the following test code for the RenewBookForm form. We start by importing our form and some Python and Django libraries to help test test time-related functionality. We then declare our form test class in the same way as we did for models, using a descriptive name for our TestCase-derived test class.

+ +
from django.test import TestCase
+
+# Create your tests here.
+
+import datetime
+from django.utils import timezone
+from catalog.forms import RenewBookForm
+
+class RenewBookFormTest(TestCase):
+
+    def test_renew_form_date_field_label(self):
+        form = RenewBookForm()
+        self.assertTrue(form.fields['renewal_date'].label == None or form.fields['renewal_date'].label == 'renewal date')
+
+    def test_renew_form_date_field_help_text(self):
+        form = RenewBookForm()
+        self.assertEqual(form.fields['renewal_date'].help_text,'Enter a date between now and 4 weeks (default 3).')
+
+    def test_renew_form_date_in_past(self):
+        date = datetime.date.today() - datetime.timedelta(days=1)
+        form_data = {'renewal_date': date}
+        form = RenewBookForm(data=form_data)
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_too_far_in_future(self):
+        date = datetime.date.today() + datetime.timedelta(weeks=4) + datetime.timedelta(days=1)
+        form_data = {'renewal_date': date}
+        form = RenewBookForm(data=form_data)
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_today(self):
+        date = datetime.date.today()
+        form_data = {'renewal_date': date}
+        form = RenewBookForm(data=form_data)
+        self.assertTrue(form.is_valid())
+
+    def test_renew_form_date_max(self):
+        date = timezone.now() + datetime.timedelta(weeks=4)
+        form_data = {'renewal_date': date}
+        form = RenewBookForm(data=form_data)
+        self.assertTrue(form.is_valid())
+
+ +

The first two functions test that the field's label and help_text are as expected. We have to access the field using the fields dictionary (e.g. form.fields['renewal_date']). Note here that we also have to test whether the label value is None, because even though Django will render the correct label it returns None if the value is not explicitly set.

+ +

The rest of the functions test that the form is valid for renewal dates just inside the acceptable range and invalid for values outside the range. Note how we construct test date values around our current date (datetime.date.today()) using datetime.timedelta() (in this case specifying a number of days or weeks). We then just create the form, passing in our data, and test if it is valid.

+ +
+

Note: Here we don't actually use the database or test client. Consider modifying these tests to use SimpleTestCase.

+ +

We also need to validate that the correct errors are raised if the form is invalid, however this is usually done as part of view processing, so we'll take care of that in the next section.

+
+ +

That's all for forms; we do have some others, but they are automatically created by our generic class-based editing views, and should be tested there! Run the tests and confirm that our code still passes!

+ +

Vistas

+ +

To validate our view behaviour we use the Django test Client. This class acts like a dummy web browser that we can use to simulate GET and POST requests on a URL and observe the response. We can see almost everything about the response, from low-level HTTP (result headers and status codes) through to the template we're using to render the HTML and the context data we're passing to it. We can also see the chain of redirects (if any) and check the URL and status code at each step. This allows us to verify that each view is doing what is expected.

+ +

Let's start with one of our simplest views, which provides a list of all Authors. This is displayed at URL /catalog/authors/ (an URL named 'authors' in the URL configuration).

+ +
class AuthorListView(generic.ListView):
+    model = Author
+    paginate_by = 10
+
+ +

As this is a generic list view almost everything is done for us by Django. Arguably if you trust Django then the only thing you need to test is that the view is accessible at the correct URL and can be accessed using its name. However if you're using a test-driven development process you'll start by writing tests that confirm that the view displays all Authors, paginating them in lots of 10.

+ +

Open the /catalog/tests/test_views.py file and replace any existing text with the following test code for AuthorListView. As before we import our model and some useful classes. In the setUpTestData() method we set up a number of Author objects so that we can test our pagination.

+ +
from django.test import TestCase
+
+# Create your tests here.
+
+from catalog.models import Author
+from django.urls import reverse
+
+class AuthorListViewTest(TestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        #Create 13 authors for pagination tests
+        number_of_authors = 13
+        for author_num in range(number_of_authors):
+            Author.objects.create(first_name='Christian %s' % author_num, last_name = 'Surname %s' % author_num,)
+
+    def test_view_url_exists_at_desired_location(self):
+        resp = self.client.get('/catalog/authors/')
+        self.assertEqual(resp.status_code, 200)
+
+    def test_view_url_accessible_by_name(self):
+        resp = self.client.get(reverse('authors'))
+        self.assertEqual(resp.status_code, 200)
+
+    def test_view_uses_correct_template(self):
+        resp = self.client.get(reverse('authors'))
+        self.assertEqual(resp.status_code, 200)
+
+        self.assertTemplateUsed(resp, 'catalog/author_list.html')
+
+    def test_pagination_is_ten(self):
+        resp = self.client.get(reverse('authors'))
+        self.assertEqual(resp.status_code, 200)
+        self.assertTrue('is_paginated' in resp.context)
+        self.assertTrue(resp.context['is_paginated'] == True)
+        self.assertTrue( len(resp.context['author_list']) == 10)
+
+    def test_lists_all_authors(self):
+        #Get second page and confirm it has (exactly) remaining 3 items
+        resp = self.client.get(reverse('authors')+'?page=2')
+        self.assertEqual(resp.status_code, 200)
+        self.assertTrue('is_paginated' in resp.context)
+        self.assertTrue(resp.context['is_paginated'] == True)
+        self.assertTrue( len(resp.context['author_list']) == 3)
+ +

All the tests use the client (belonging to our TestCase's derived class) to simulate a GET request and get a response (resp). The first version checks a specific URL (note, just the specific path without the domain) while the second generates the URL from its name in the URL configuration.

+ +
resp = self.client.get('/catalog/authors/')
+resp = self.client.get(reverse('authors'))
+
+ +

Once we have the response we query it for its status code, the template used, whether or not the response is paginated, the number of items returned, and the total number of items.

+ +

The most interesting variable we demonstrate above is resp.context, which is the context variable passed to the template by the view. This is incredibly useful for testing, because it allows us to confirm that our template is getting all the data it needs. In other words we can check that we're using the intended template and what data the template is getting, which goes a long way to verifying that any rendering issues are solely due to template.

+ +

Views that are restricted to logged in users

+ +

In some cases you'll want to test a view that is restricted to just logged in users. For example our LoanedBooksByUserListView is very similar to our previous view but is only available to logged in users, and only displays BookInstance records that are borrowed by the current user, have the 'on loan' status, and are ordered "oldest first".

+ +
from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
+    """
+    Generic class-based view listing books on loan to current user.
+    """
+    model = BookInstance
+    template_name ='catalog/bookinstance_list_borrowed_user.html'
+    paginate_by = 10
+
+    def get_queryset(self):
+        return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
+ +

Add the following test code to /catalog/tests/test_views.py. Here we first use SetUp() to create some user login accounts and BookInstance objects (along with their associated books and other records) that we'll use later in the tests. Half of the books are borrowed by each test user, but we've initially set the status of all books to "maintenance". We've used SetUp() rather than setUpTestData() because we'll be modifying some of these objects later.

+ +
+

Note: The setUp() code below creates a book with a specified Language, but your code may not include the Language model as this was created as a challenge. If this is the case, simply  comment out the parts of the code that create or import Language objects. You should also do this in the RenewBookInstancesViewTest section that follows.

+
+ +
import datetime
+from django.utils import timezone
+
+from catalog.models import BookInstance, Book, Genre, Language
+from django.contrib.auth.models import User #Required to assign User as a borrower
+
+class LoanedBookInstancesByUserListViewTest(TestCase):
+
+    def setUp(self):
+        #Create two users
+        test_user1 = User.objects.create_user(username='testuser1', password='12345')
+        test_user1.save()
+        test_user2 = User.objects.create_user(username='testuser2', password='12345')
+        test_user2.save()
+
+        #Create a book
+        test_author = Author.objects.create(first_name='John', last_name='Smith')
+        test_genre = Genre.objects.create(name='Fantasy')
+        test_language = Language.objects.create(name='English')
+        test_book = Book.objects.create(title='Book Title', summary = 'My book summary', isbn='ABCDEFG', author=test_author, language=test_language)
+        # Create genre as a post-step
+        genre_objects_for_book = Genre.objects.all()
+        test_book.genre.set(genre_objects_for_book) #Direct assignment of many-to-many types not allowed.
+        test_book.save()
+
+        #Create 30 BookInstance objects
+        number_of_book_copies = 30
+        for book_copy in range(number_of_book_copies):
+            return_date= timezone.now() + datetime.timedelta(days=book_copy%5)
+            if book_copy % 2:
+                the_borrower=test_user1
+            else:
+                the_borrower=test_user2
+            status='m'
+            BookInstance.objects.create(book=test_book,imprint='Unlikely Imprint, 2016', due_back=return_date, borrower=the_borrower, status=status)
+
+    def test_redirect_if_not_logged_in(self):
+        resp = self.client.get(reverse('my-borrowed'))
+        self.assertRedirects(resp, '/accounts/login/?next=/catalog/mybooks/')
+
+    def test_logged_in_uses_correct_template(self):
+        login = self.client.login(username='testuser1', password='12345')
+        resp = self.client.get(reverse('my-borrowed'))
+
+        #Check our user is logged in
+        self.assertEqual(str(resp.context['user']), 'testuser1')
+        #Check that we got a response "success"
+        self.assertEqual(resp.status_code, 200)
+
+        #Check we used correct template
+        self.assertTemplateUsed(resp, 'catalog/bookinstance_list_borrowed_user.html')
+
+ +

To verify that the view will redirect to a login page if the user is not logged in we use assertRedirects, as demonstrated in test_redirect_if_not_logged_in(). To verify that the page is displayed for a logged in user we first log in our test user, and then access the page again and check that we get a status_code of 200 (success). 

+ +

The rest of the test verify that our view only returns books that are on loan to our current borrower. Copy the (self-explanatory) code at the end of the test class above.

+ +
    def test_only_borrowed_books_in_list(self):
+        login = self.client.login(username='testuser1', password='12345')
+        resp = self.client.get(reverse('my-borrowed'))
+
+        #Check our user is logged in
+        self.assertEqual(str(resp.context['user']), 'testuser1')
+        #Check that we got a response "success"
+        self.assertEqual(resp.status_code, 200)
+
+        #Check that initially we don't have any books in list (none on loan)
+        self.assertTrue('bookinstance_list' in resp.context)
+        self.assertEqual( len(resp.context['bookinstance_list']),0)
+
+        #Now change all books to be on loan
+        get_ten_books = BookInstance.objects.all()[:10]
+
+        for copy in get_ten_books:
+            copy.status='o'
+            copy.save()
+
+        #Check that now we have borrowed books in the list
+        resp = self.client.get(reverse('my-borrowed'))
+        #Check our user is logged in
+        self.assertEqual(str(resp.context['user']), 'testuser1')
+        #Check that we got a response "success"
+        self.assertEqual(resp.status_code, 200)
+
+        self.assertTrue('bookinstance_list' in resp.context)
+
+        #Confirm all books belong to testuser1 and are on loan
+        for bookitem in resp.context['bookinstance_list']:
+            self.assertEqual(resp.context['user'], bookitem.borrower)
+            self.assertEqual('o', bookitem.status)
+
+    def test_pages_ordered_by_due_date(self):
+
+        #Change all books to be on loan
+        for copy in BookInstance.objects.all():
+            copy.status='o'
+            copy.save()
+
+        login = self.client.login(username='testuser1', password='12345')
+        resp = self.client.get(reverse('my-borrowed'))
+
+        #Check our user is logged in
+        self.assertEqual(str(resp.context['user']), 'testuser1')
+        #Check that we got a response "success"
+        self.assertEqual(resp.status_code, 200)
+
+        #Confirm that of the items, only 10 are displayed due to pagination.
+        self.assertEqual( len(resp.context['bookinstance_list']),10)
+
+        last_date=0
+        for copy in resp.context['bookinstance_list']:
+            if last_date==0:
+                last_date=copy.due_back
+            else:
+                self.assertTrue(last_date <= copy.due_back)
+ +

You could also add pagination tests, should you so wish!

+ +

Testing views with forms

+ +

Testing views with forms is a little more complicated than in the cases above, because you need to test more code paths: initial display, display after data validation has failed, and display after validation has succeeded. The good news is that we use the client for testing in almost exactly the same way as we did for display-only views.

+ +

To demonstrate, let's write some tests for the view used to renew books (renew_book_librarian()):

+ +
from .forms import RenewBookForm
+
+@permission_required('catalog.can_mark_returned')
+def renew_book_librarian(request, pk):
+    """
+    View function for renewing a specific BookInstance by librarian
+    """
+    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+ +

We'll need to test that the view is only available to users who have the can_mark_returned permission, and that users are redirected to an HTTP 404 error page if they attempt to renew a BookInstance that does not exist. We should check that the initial value of the form is seeded with a date three weeks in the future, and that if validation succeeds we're redirected to the "all-borrowed books" view. As part checking the validation-fail tests we'll also check that our form is sending the appropriate error messages.

+ +

Add the first part of the test class (shown below) to the bottom of /catalog/tests/test_views.py. This creates two users and two book instances, but only gives one user the permission required to access the view. The code to grant permissions during tests is shown in bold:

+ +
from django.contrib.auth.models import Permission # Required to grant the permission needed to set a book as returned.
+
+class RenewBookInstancesViewTest(TestCase):
+
+    def setUp(self):
+        #Create a user
+        test_user1 = User.objects.create_user(username='testuser1', password='12345')
+        test_user1.save()
+
+        test_user2 = User.objects.create_user(username='testuser2', password='12345')
+        test_user2.save()
+        permission = Permission.objects.get(name='Set book as returned')
+        test_user2.user_permissions.add(permission)
+        test_user2.save()
+
+        #Create a book
+        test_author = Author.objects.create(first_name='John', last_name='Smith')
+        test_genre = Genre.objects.create(name='Fantasy')
+        test_language = Language.objects.create(name='English')
+        test_book = Book.objects.create(title='Book Title', summary = 'My book summary', isbn='ABCDEFG', author=test_author, language=test_language,)
+        # Create genre as a post-step
+        genre_objects_for_book = Genre.objects.all()
+        test_book.genre.set(genre_objects_for_book) # Direct assignment of many-to-many types not allowed.
+        test_book.save()
+
+        #Create a BookInstance object for test_user1
+        return_date= datetime.date.today() + datetime.timedelta(days=5)
+        self.test_bookinstance1=BookInstance.objects.create(book=test_book,imprint='Unlikely Imprint, 2016', due_back=return_date, borrower=test_user1, status='o')
+
+        #Create a BookInstance object for test_user2
+        return_date= datetime.date.today() + datetime.timedelta(days=5)
+        self.test_bookinstance2=BookInstance.objects.create(book=test_book,imprint='Unlikely Imprint, 2016', due_back=return_date, borrower=test_user2, status='o')
+ +

Add the following tests to the bottom of the test class. These check that only users with the correct permissions (testuser2) can access the view. We check all the cases: when the user is not logged in, when a user is logged in but does not have the correct permissions, when the user has permissions but is not the borrower (should succeed), and what happens when they try to access a BookInstance that doesn't exist. We also check that the correct template is used.

+ +
    def test_redirect_if_not_logged_in(self):
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}) )
+        #Manually check redirect (Can't use assertRedirect, because the redirect URL is unpredictable)
+        self.assertEqual( resp.status_code,302)
+        self.assertTrue( resp.url.startswith('/accounts/login/') )
+
+    def test_redirect_if_logged_in_but_not_correct_permission(self):
+        login = self.client.login(username='testuser1', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}) )
+
+        #Manually check redirect (Can't use assertRedirect, because the redirect URL is unpredictable)
+        self.assertEqual( resp.status_code,302)
+        self.assertTrue( resp.url.startswith('/accounts/login/') )
+
+    def test_logged_in_with_permission_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance2.pk,}) )
+
+        #Check that it lets us login - this is our book and we have the right permissions.
+        self.assertEqual( resp.status_code,200)
+
+    def test_logged_in_with_permission_another_users_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}) )
+
+        #Check that it lets us login. We're a librarian, so we can view any users book
+        self.assertEqual( resp.status_code,200)
+
+    def test_HTTP404_for_invalid_book_if_logged_in(self):
+        import uuid
+        test_uid = uuid.uuid4() #unlikely UID to match our bookinstance!
+        login = self.client.login(username='testuser2', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':test_uid,}) )
+        self.assertEqual( resp.status_code,404)
+
+    def test_uses_correct_template(self):
+        login = self.client.login(username='testuser2', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}) )
+        self.assertEqual( resp.status_code,200)
+
+        #Check we used correct template
+        self.assertTemplateUsed(resp, 'catalog/book_renew_librarian.html')
+
+ +

Add the next test method, as shown below. This checks that the initial date for the form is three weeks in the future. Note how we are able to access the value of the initial value of the form field (shown in bold).

+ +
    def test_form_renewal_date_initially_has_date_three_weeks_in_future(self):
+        login = self.client.login(username='testuser2', password='12345')
+        resp = self.client.get(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}) )
+        self.assertEqual( resp.status_code,200)
+
+        date_3_weeks_in_future = datetime.date.today() + datetime.timedelta(weeks=3)
+        self.assertEqual(resp.context['form'].initial['renewal_date'], date_3_weeks_in_future )
+
+ +

The next test (add this to the class too) checks that the view redirects to a list of all borrowed books if renewal succeeds. What differs here is that for the first time we show how you can POST data using the client. The post data is the second argument to the post function, and is specified as a dictionary of key/values.

+ +
    def test_redirects_to_all_borrowed_book_list_on_success(self):
+        login = self.client.login(username='testuser2', password='12345')
+        valid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=2)
+        resp = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future} )
+        self.assertRedirects(resp, reverse('all-borrowed') )
+
+ +
+

The all-borrowed view was added as a challenge, and your code may instead redirect to the home page '/'. If so, modify the last two lines of the test code to be like the code below. The follow=True in the request ensures that the request returns the final destination URL (hence checking /catalog/ rather than /).

+ +
 resp = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future},follow=True )
+ self.assertRedirects(resp, '/catalog/')
+
+ +

Copy the last two functions into the class, as seen below. These again test POST requests, but in this case with invalid renewal dates. We use assertFormError() to verify that the error messages are as expected.

+ +
    def test_form_invalid_renewal_date_past(self):
+        login = self.client.login(username='testuser2', password='12345')
+        date_in_past = datetime.date.today() - datetime.timedelta(weeks=1)
+        resp = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':date_in_past} )
+        self.assertEqual( resp.status_code,200)
+        self.assertFormError(resp, 'form', 'renewal_date', 'Invalid date - renewal in past')
+
+    def test_form_invalid_renewal_date_future(self):
+        login = self.client.login(username='testuser2', password='12345')
+        invalid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=5)
+        resp = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':invalid_date_in_future} )
+        self.assertEqual( resp.status_code,200)
+        self.assertFormError(resp, 'form', 'renewal_date', 'Invalid date - renewal more than 4 weeks ahead')
+
+ +

The same sorts of techniques can be used to test the other view.

+ +

Templates

+ +

Django provides test APIs to check that the correct template is being called by your views, and to allow you to verify that the correct information is being sent. There is however no specific API support for testing in Django that your HTML output is rendered as expected.

+ + + +

Django's test framework can help you write effective unit and integration tests — we've only scratched the surface of what the underlying unittest framework can do, let alone Django's additions (for example, check out how you can use unittest.mock to patch third party libraries so you can more thoroughly test your own code).

+ +

While there are numerous other test tools that you can use, we'll just highlight two:

+ + + +

Reto para mi mismo

+ +

There are a lot more models and views we can test. As a simple task, try to create a test case for the AuthorCreate view.

+ +
class AuthorCreate(PermissionRequiredMixin, CreateView):
+    model = Author
+    fields = '__all__'
+    initial={'date_of_death':'12/10/2016',}
+    permission_required = 'catalog.can_mark_returned'
+ +

Remember that you need to check anything that you specify or that is part of the design. This will include who has access, the initial date, the template used, and where the view redirects on success.

+ +

Resumen

+ +

Writing test code is neither fun nor glamorous, and is consequently often left to last (or not at all) when creating a website. It is however an essential part of making sure that your code is safe to release after making changes, and cost-effective to maintain.

+ +

In this tutorial we've shown you how to write and run tests for your models, forms, and views. Most importantly we've provided a brief summary of what you should test, which is often the hardest thing to work out when your getting started. There is a lot more to know, but even with what you've learned already you should be able to create effective unit tests for your websites.

+ +

The next and final tutorial shows how you can deploy your wonderful (and fully tested!) Django website.

+ +

Mirar tambien

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/tutorial_local_library_website/index.html b/files/es/learn/server-side/django/tutorial_local_library_website/index.html new file mode 100644 index 0000000000..a7450fafd0 --- /dev/null +++ b/files/es/learn/server-side/django/tutorial_local_library_website/index.html @@ -0,0 +1,103 @@ +--- +title: 'Tutorial Django: El Sitio Web de La Biblioteca Local' +slug: Learn/Server-side/Django/Tutorial_local_library_website +tags: + - Aprendizaje + - Artículo + - Codificación de scripts + - Guía + - Principiante + - Tutorial + - django + - lado servidor +translation_of: Learn/Server-side/Django/Tutorial_local_library_website +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}
+ +

El primer artículo de nuestra serie de tutoriales prácticos explica qué puedes aprender, y proporciona una visión general del sitio web de ejemplo de "biblioteca local" en el que estaremos trabajando y evolucionando en artículos subsiguientes.

+ + + + + + + + + + + + +
Pre-requisitos: +

Leer la Introducción a Django. Durante los siguientes artículos necesitarás tener levantado un entorno de desarrollo Django

+
Objetivo: +

Presentar el ejemplo de aplicación usado en este tutorial, y permitir que los lectores comprendan los temas que se tratarán aquí. 

+
+ +

Visión general

+ +

Bienvenidos al tutorial de MDN sobre la "Biblioteca Local" Django en el que desarrollaremos un sitio web que podría usarse para gestionar el catálogo de una biblioteca local. 

+ +

En esta serie de tutoriales:

+ + + +

Has aprendido algo de estos tópicos ya, y tocado otros brevemente. Al final de esta serie de tutoriales sabrás lo suficiente para desarrollar aplicaciones simples Django por tí mismo.

+ +

El sitio web de la Biblioteca Local

+ +

BibliotecaLocal es el nombre del sitio web que crearemos para evolucionar a lo largo del curso de esta serie de tutoriales. Como habrás supuesto, el propósito de este sitio web es proporcionar un catálogo online para una pequeña biblioteca local, en la que los usuarios pueden explorar los libros disponibles y gestionar sus cuentas.

+ +

Este ejemplo ha sido seleccionado cuidadosamente porque puede escalar para mostrar tanto mucho detalle como poco según necesitemos, y puede usarse para mostrar casi cualquier característica de Django. Más importante aún, nos permite proporcionar un camino guiado a través de las funcionalidades más importantes del framework web Django:

+ + + +

Incluso aunque es un ejemplo muy extenso, se llama BibliotecaLocal por una razón — esperamos mostrar el mínimo de información que te ayude a ponerte en marcha con Django rápidamente. Como resultado almacenaremos información sobre libros, copias de libros, autores y otras información clave. Sin embargo, no almacenaremos información sobre otros elementos que una biblioteca podría almacenar, ni proporcionaremos la infraestructura necesaría para mantener multiples sitios de bibliotecas u otras características de una "gran biblioteca".

+ +

Estoy atascado, ¿Donde puedo encontrar el código fuente?

+ +

A medida que avances a través del tutorial te proporcionaremos los fragmentos de código apropiados para que copies y pegues en cada punto, y habrá otro código que esperamos que puedas entender tú mismo (con algo de ayuda).

+ +

Si te quedas atascado, puedes encontrar la versión completamente desarrollada en el sitio web de Github aquí.

+ +

Resumen

+ +

Ahora que sabes un poco más sobre el sitio de la BibliotecaLocal y lo que vas a aprender, es hora de empezar a crear el esqueleto(estructura) de nuestro proyecto.

+ +

{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/django/web_application_security/index.html b/files/es/learn/server-side/django/web_application_security/index.html new file mode 100644 index 0000000000..e00a1771bb --- /dev/null +++ b/files/es/learn/server-side/django/web_application_security/index.html @@ -0,0 +1,176 @@ +--- +title: Seguridad de las aplicaciones web Django +slug: Learn/Server-side/Django/web_application_security +translation_of: Learn/Server-side/Django/web_application_security +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Deployment", "Learn/Server-side/Django/django_assessment_blog", "Learn/Server-side/Django")}}
+ +

Proteger los datos de los usuarios es una parte esencial de cualquier diseño de un sitio web. Previamente ya explicamos algunas de las amenazas de seguridad más comunes en el artículo Seguridad Web — este artículo proporciona una demostración práctica de cómo las protecciones integradas de Django gestionan estas amenazas.

+ + + + + + + + + + + + +
Prerrequisitos:Lee la documentación de la Programación del Lado del servidor "Seguridad de la aplicación web de Django". Completa todos los temas del Tutorial de Django (incluyendo este) o por lo menos el Tutorial de Django Parte 9: Trabajar con formularios web.
Objetivo:Comprender las cosas principales que debes hacer (y las que no debes) para proteger su aplicación web de Django.
+ +

Overview

+ +

The Website security topic provides an overview of what website security means for server-side design, and some of the more common threats that you may need to protect against. One of the key messages in that article is that almost all attacks are successful when the web application trusts data from the browser.

+ +
+

Important: The single most important lesson you can learn about website security is to never trust data from the browser. This includes GET request data in URL parameters, POST data, HTTP headers and cookies, user-uploaded files, etc. Always check and sanitize all incoming data. Always assume the worst.

+
+ +

The good news for Django users is that many of the more common threats are handled by the framework! The Security in Django (Django docs) article explains Django's security features and how to secure a Django-powered website.

+ +

Common threats/protections

+ +

Rather than duplicate the Django documentation here, in this article we'll demonstrate just a few of the security features in the context of our Django LocalLibrary tutorial.

+ +

Cross site scripting (XSS)

+ +

XSS is a term used to describe a class of attacks that allow an attacker to inject client-side scripts through the website into the browsers of other users. This is usually achieved by storing malicious scripts in the database where they can be retrieved and displayed to other users, or by getting users to click a link that will cause the attacker’s JavaScript to be executed by the user’s browser.

+ +

Django's template system protects you against the majority of XSS attacks by escaping specific characters that are "dangerous" in HTML. We can demonstrate this by attempting to inject some JavaScript into our LocalLibrary website using the Create-author form we set up in Django Tutorial Part 9: Working with forms.

+ +
    +
  1. Start the website using the development server (python3 manage.py runserver).
  2. +
  3. Open the site in your local browser and login to your superuser account.
  4. +
  5. Navigate to the author-creation page (which should be at URL: http://127.0.0.1:8000/catalog/author/create/).
  6. +
  7. Enter names and date details for a new user, and then append the following text to the Last Name field:
    + <script>alert('Test alert');</script>.
    + Author Form XSS test +
    +

    Note: This is a harmless script that, if executed, will display an alert box in your browser. If the alert is displayed when you submit the record then the site is vulnerable to XSS threats.

    +
    +
  8. +
  9. Press Submit to save the record.
  10. +
  11. When you save the author it will be displayed as shown below. Because of the XSS protections the alert() should not be run. Instead the script is displayed as plain text.Author detail view XSS test
  12. +
+ +

If you view the page HTML source code, you can see that the dangerous characters for the script tags have been turned into their harmless escape code equivalents (e.g. > is now &gt;)

+ +
<h1>Author: Boon&lt;script&gt;alert(&#39;Test alert&#39;);&lt;/script&gt;, David (Boonie) </h1>
+
+ +

Using Django templates protects you against the majority of XSS attacks. However it is possible to turn off this protection, and the protection isn't automatically applied to all tags that wouldn't normally be populated by user input (for example, the help_text in a form field is usually not user-supplied, so Django doesn't escape those values).

+ +

It is also possible for XSS attacks to originate from other untrusted source of data, such as cookies, Web services or uploaded files (whenever the data is not sufficiently sanitized before including in a page). If you're displaying data from these sources, then you may need to add your own sanitisation code.

+ +

Cross site request forgery (CSRF) protection

+ +

CSRF attacks allow a malicious user to execute actions using the credentials of another user without that user’s knowledge or consent. For example consider the case where we have a hacker who wants to create additional authors for our LocalLibrary.

+ +
+

Note: Obviously our hacker isn't in this for the money! A more ambitious hacker could use the same approach on other sites to perform much more harmful tasks (e.g. transfer money to their own accounts, etc.)

+
+ +

In order to do this, they might create an HTML file like the one below, which contains an author-creation form (like the one we used in the previous section) that is submitted as soon as the file is loaded. They would then send the file to all the Librarians and suggest that they open the file (it contains some harmless information, honest!). If the file is opened by any logged in librarian, then the form would be submitted with their credentials and a new author would be created.

+ +
<html>
+<body onload='document.EvilForm.submit()'>
+
+<form action="http://127.0.0.1:8000/catalog/author/create/" method="post" name='EvilForm'>
+  <table>
+    <tr><th><label for="id_first_name">First name:</label></th><td><input id="id_first_name" maxlength="100" name="first_name" type="text" value="Mad" required /></td></tr>
+    <tr><th><label for="id_last_name">Last name:</label></th><td><input id="id_last_name" maxlength="100" name="last_name" type="text" value="Man" required /></td></tr>
+    <tr><th><label for="id_date_of_birth">Date of birth:</label></th><td><input id="id_date_of_birth" name="date_of_birth" type="text" /></td></tr>
+    <tr><th><label for="id_date_of_death">Died:</label></th><td><input id="id_date_of_death" name="date_of_death" type="text" value="12/10/2016" /></td></tr>
+  </table>
+  <input type="submit" value="Submit" />
+</form>
+
+</body>
+</html>
+
+ +

Run the development web server, and log in with your superuser account. Copy the text above into a file and then open it in the browser. You should get a CSRF error, because Django has protection against this kind of thing!

+ +

The way the protection is enabled is that you include the {% csrf_token %} template tag in your form definition. This token is then rendered in your HTML as shown below, with a value that is specific to the user on the current browser.

+ +
<input type='hidden' name='csrfmiddlewaretoken' value='0QRWHnYVg776y2l66mcvZqp8alrv4lb8S8lZ4ZJUWGZFA5VHrVfL2mpH29YZ39PW' />
+
+ +

Django generates a user/browser specific key and will reject forms that do not contain the field, or that contain an incorrect field value for the user/browser.

+ +

To use this type of attack the hacker now has to discover and include the CSRF key for the specific target user. They also can't use the "scattergun" approach of sending a malicious file to all librarians and hoping that one of them will open it, since the CSRF key is browser specific.

+ +

Django's CSRF protection is turned on by default. You should always use the {% csrf_token %} template tag in your forms and use POST for requests that might change or add data to the database.

+ +

Other protections

+ +

Django also provides other forms of protection (most of which would be hard or not particularly useful to demonstrate):

+ +
+
SQL injection protection
+
SQL injection vulnerabilities enable malicious users to execute arbitrary SQL code on a database, allowing data to be accessed, modified, or deleted irrespective of the user's permissions. In almost every case you'll be accessing the database using Django’s querysets/models, so the resulting SQL will be properly escaped by the underlying database driver. If you do need to write raw queries or custom SQL then you'll need to explicitly think about preventing SQL injection.
+
Clickjacking protection
+
In this attack a malicious user hijacks clicks meant for a visible top level site and routes them to a hidden page beneath. This technique might be used, for example, to display a legitimate bank site but capture the login credentials in an invisible <iframe> controlled by the attacker. Django contains clickjacking protection in the form of the X-Frame-Options middleware which, in a supporting browser, can prevent a site from being rendered inside a frame.
+
Enforcing SSL/HTTPS
+
SSL/HTTPS can be enabled on the web server in order to encrypt all traffic between the site and browser, including authentication credentials that would otherwise be sent in plain text (enabling HTTPS is highly recommended). If HTTPS is enabled then Django provides a number of other protections you can use:
+
+ + + +
+
Host header validation
+
Use ALLOWED_HOSTS to only accept requests from trusted hosts.
+
+ +

There are many other protections, and caveats to the usage of the above mechanisms. While we hope that this has given you an overview of what Django offers, you should still read the Django security documentation.

+ + + +

Summary

+ +

Django has effective protections against a number of common threats, including XSS and CSRF attacks. In this article we've demonstrated how those particular threats are handled by Django in our LocalLibrary website. We've also provided a brief overview of some of the other protections.

+ +

This has been a very brief foray into web security. We strongly recommend that you read Security in Django to gain a deeper understanding.

+ +

The next and final step in this module about Django is to complete the assessment task.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Deployment", "Learn/Server-side/Django/django_assessment_blog", "Learn/Server-side/Django")}}

+ +

En este módulo

+ + diff --git a/files/es/learn/server-side/express_nodejs/development_environment/index.html b/files/es/learn/server-side/express_nodejs/development_environment/index.html new file mode 100644 index 0000000000..40a96d56e4 --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/development_environment/index.html @@ -0,0 +1,407 @@ +--- +title: Setting up a Node development environment +slug: Learn/Server-side/Express_Nodejs/development_environment +tags: + - Aprender + - Entorno de Desarrollo + - Express + - JavaScript + - Node + - nodejs + - npm +translation_of: Learn/Server-side/Express_Nodejs/development_environment +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Introduction", "Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs")}}
+ +

Ahora que sabes para que sirve Express, nosotros te vamos a mostrar como preparar y testear un entorno de desarrollo Node/Express en: Windows, Linux (Ubuntu), y macOS. Este artículo te va a dar todo lo que se necesita para poder empezar a desarrollar apps en Express, sin importar el sistema operativo que se use.

+ + + + + + + + + + + + +
Prerequisitos:Saber como abrir una terminal / línea de comando. Saber como instalar paquetes de software en su sistema operativo de su computadora de desarrollo.
Objectivo:Configurar un ambiente de desarrollo para Express (X.XX) en su computadora.
+ +

Express ambiente de desarrollo reseña

+ +

NodeExpress hacen muy fácil configurar su computadora con el propósito de iniciar el desarrollo de aplicaciones web. Esta seccion provee una reseña de qué herramientas son necesarias, explica algunos de los métodos más simples para instalar Node (y Express) en Ubuntu, macOS y Windows, y muestra como puede probar su instalación.

+ +

Qué es el ambiente de desarrollo Express?

+ +

El ambiente de desarrollo Express incluye una instalación de Nodejs, el NPM administrador de paquetes, y (opcionalmente) el Generador de Aplicaciones de Express en su computadora local.

+ +

Node y el administrador de paquetes NPM se instalan juntos desde paquetes binarios, instaladores, administradores de paquetes del sistema operativo o desde los fuentes (como se muestra en las siguientes secciónes). Express es entonces instalado por NPM como una dependencia individual de sus aplicaciones web Express (conjuntamente con otras librerías como motores de plantillas, controladores de bases de datos, middleware de autenticación, middleware para servir archivos estáticos, etc.)

+ +

NPM puede ser usado también para (globalmente) instalar el Generador de Aplicaciones de Express, una herramienta manual para crear la estructura de las web apps de Express que siguen el  patrón MVC . El generador de aplicaciones es opcional porque no necesita utilizar esta herramienta para  crear apps que usan Express, o construir apps Express que tienen el mismo diseño arquitectónico o dependencias. No obstante estaremos usandolo, porque hace mucho más fácil, y promueve una estrucura modular de aplicación.

+ +
+

Nota: A diferencia de otros frameworks web , el ambiente de desarrollo no incluye un servidor web independiente. Una aplicación web Node/Express  crea y ejecuta su propio servidor web!

+
+ +

Hay otras herramientas periféricas que son parte de un ambiente de desarrollo típico, incluyendo editores de texto o IDEs para edición de código, y herramientas de administración de control de fuentes como Git para administrar con seguridad diferentes versiones de su codigo. Asumimos que usted ya tiene instaladas esta clase de herramientas (en particular un editor de texto).

+ +

Qué sistemas operativos son soportados?

+ +

Node puede ser ejecutado en Windows, macOS, varias "versiones" de Linux, Docker, etc. (hay una lista completa de paginas de Downloads de nodejs). Casi cualquier computadora personal podría tener el desempeño necesario para ejecutar Node durante el desarrollo. Express es ejecutado en un ambiente Node, y por lo tanto puede ejecutarse en cualquier plataforma que ejecute Node.

+ +

En este articulo proveemos instruciones para configurarlo para Windows, macOS, and Ubuntu Linux.

+ +

¿Qué versión de Node/Express puedo usar?

+ +

Hay varias versiones de Node — recientes que contienen reparacion de bugs, soporte para versiones mas recientes de ECMAScript (JavaScript) estandares, y mejoras a las APIs de Node . 

+ +

Generalmente se debe usar la versión más reciente SLP (soporte de largo-plazo), una versión como esta es más estable que la versión "actual", mientras que sigue teniendo características relativamente recientes  (y continua siendo activamente actualizado). Debería utilizar la versión Actual si necesita una característica que no esta presente en la versión SLP.

+ +

Para Express siempre se debe utilizar la versión más reciente.

+ +

¿Qué pasa con bases de datos y otras dependencias?

+ +

Otras dependencias, tales como los controladores de bases de datos, motores de plantillas, motores de autenticación, etc. son parte de la aplicación, y son importadas dentro del ambiente de la aplicación utilizando el administrador de paquetes NPM. Estos los discutiremos en artículos posteriores app-specific.

+ +

Instalar Node

+ +

Para poder utilizar Express primero tiene que instalar Nodejs y el Administrador de Paquetes de Node (NPM) en su sistema operativo. Las siguientes secciones explican la forma más fácil de instalar la versión Soporte de Largo-Plazo (SLP) de Nodejs en Ubuntu Linux 16.04, macOS, y Windows 10.

+ +
+

Tip: Las secciones de abajo muestran la forma más facil de instalar Node y NPM en nuestras plataformas de sistemas operativo a elegir. Si esta utilizando otro SO o solo quiere ver alguna de otros enfoques para las plataformas actuales entonce vea Instalando Node.js via administrador de paquetes (nodejs.org).

+
+ +

macOS y Windows

+ +

Instalar Node y NPM en Windows y macOS es sencillo, porque simplemente debe utilizar el instalador provisto:

+ +
    +
  1. Descargue el instalador requerido: +
      +
    1. Vaya a https://nodejs.org/es/
    2. +
    3. Seleccione el boton para descargar la versión LTS que es "Recomendada la mayoría de los usuarios".
    4. +
    +
  2. +
  3. Instale Node al dar doble-click en el archivo de descarga y en seguida la  instalación inicia.
  4. +
+ +

Ubuntu 18.04

+ +

La forma más fácil de instalar la versión LTS de Node 10.x es la usar el administrador de paquetes para obtenerlo del repositorio de distribuciones binarias de Ubuntu. Esto puede ser hecho muy simple al ejecutar los siguientes dos comandos en su terminal:

+ +
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
+sudo apt-get install -y nodejs
+
+ +
+

Advertencia: No instale directamente desde los repositorios normales de Ubuntu porque pueden contener versions muy antiguas de Node.

+
+ +
    +
+ +

Probar su instalación de Nodejs y NPM

+ +

La forma más fácil de probar que Node está instalado es ejecutar el comando "version" en su prompt de terminal/command y checar que una cadena de versión es devuelta:

+ +
>node -v
+v10.16.0
+ +

The administrador de paquetes NPM  de Nodejs también debería haber sido instalado y puede ser probado de la misma forma:

+ +
>npm -v
+6.9.0
+ +

Como una prueba un poco más emocionante creemos un muy básico "básico servidor node" que simplemente imprima "Hola Mundo" en el browser cuando visite la URL correcta en él:

+ +
    +
  1. Copie el siguiente texto en un archivo llamado holanode.js. Este utiliza características básicas de Node (nada desde Express) y algo de sintáxis ES6: + +
    //Load HTTP module
    +const http = require("http");
    +const hostname = '127.0.0.1';
    +const port = 3000;
    +
    +//Create HTTP server and listen on port 3000 for requests
    +const server = http.createServer((req, res) => {
    +
    +  //Set the response HTTP header with HTTP status and Content type
    +  res.statusCode = 200;
    +  res.setHeader('Content-Type', 'text/plain');
    +  res.end('Hello World\n');
    +});
    +
    +//listen for request on port 3000, and as a callback function have the port listened on logged
    +server.listen(port, hostname, () => {
    +  console.log(`Server running at http://${hostname}:${port}/`);
    +});
    +
    +
    + +

    El código importa el módulo "http" y lo usa para crear un servidor  (createServer()) que escucha las solicitudes HTTP en el puerto 3000. Luego, el script imprime un mensaje en la consola con la URL del navegador puede usar para probar el servidor. La función createServer() toma como argumento una función callback que se invocará cuando se reciba una solicitud HTTP —  esto simplemente devuelve una respuesta con un código de estado HTTP de 200 ("OK") y el texto sin formato "Hello World".

    + +
    +

    Nota:   ¡No se preocupe si aún no comprende exactamente lo que está haciendo este código! ¡Explicaremos nuestro código con mayor detalle una vez que comencemos a usar Express!

    +
    +
  2. +
  3. Inicie el servidor navegando en el mismo directorio que su archivo hellonode.js en su símbolo del sistema, y llamando a node junto con el nombre del script, así: +
    >node hellonode.js
    +Server running at http://127.0.0.1:3000/
    +
    +
  4. +
  5. Navega a la URL http://127.0.0.1:3000 . Sí todo esta funciona, el navegador simplemente debe mostrar la cadena de texto "Hello World".
  6. +
+ +

Usando NPM

+ +

Junto al propio node, NPM es la herramienta más importante para trabajar con aplicaciones de node. NPM se usa para obtener los paquetes (bibliotecas de JavaScript) que una aplicación necesita para el desarrollo, las pruebas y/o la producción, y también se puede usar para ejecutar pruebas y herramientas utilizadas en el proceso de desarrollo.

+ +
+

Nota:  Desde la perspectiva de Node, Express es solo otro paquete que necesita instalar usando NPM y luego requerir en su propio código.

+
+ +

Se puede usar NPM manualmente para buscar por separado cada paquete necesario. Por lo general, administramos las dependencias utilizando un archivo de definición de texto plano llamado package.json. Este archivo enumera todas las dependencias para un "paquete" de JavaScript específico, incluido el nombre del paquete, la versión, la descripción, el archivo inicial a ejecutar, las dependencias de producción, las dependencias de desarrollo, las versiones de Node con las que puede trabajar, etc. El archivo package.json debería contener todo lo que NPM necesita para buscar y ejecutar su aplicación (si estuviera escribiendo una biblioteca reutilizable, podría usar esta definición para cargar su paquete en el repositorio npm y ponerlo a disposición de otros usuarios).

+ +

Agregando dependencias

+ +

Los siguientes pasos muestran cómo puede usar NPM para descargar un paquete, guardarlo en las dependencias del proyecto y luego requerirlo en una aplicación Node.

+ +
+

Nota: Aquí mostramos las instrucciones para buscar e instalar el paquete Express. Más adelante mostraremos cómo este paquete y otros ya están especificados para nosotros utilizando el Generador de aplicaciones Express. Esta sección se proporciona porque es útil para comprender cómo funciona NPM y qué está creando el generador de aplicaciones.

+
+ +
    +
  1. Primero cree un directorio para su nueva aplicación y acceda a él: + +
    mkdir myapp
    +cd myapp
    +
  2. +
  3. Use el comando npm init para crear un archivo package.json para su aplicación. Este comando le solicita varias cosas, incluido el nombre y la versión de su aplicación y el nombre del archivo de punto de entrada inicial (de forma predeterminada, esto es index.js). Por ahora, solo acepte los valores predeterminados:
  4. +
  5. +
    npm init
    + +

    Si muestra el archivo package.json (cat package.json), verá los valores predeterminados que aceptó, que finalizarán con la licencia.

    + +
    {
    +  "name": "myapp",
    +  "version": "1.0.0",
    +  "description": "",
    +  "main": "index.js",
    +  "scripts": {
    +    "test": "echo \"Error: no test specified\" && exit 1"
    +  },
    +  "author": "",
    +  "license": "ISC"
    +}
    +
    +
  6. +
  7. Ahora instale Express en el directorio myapp y guárdelo en la lista de dependencias de su archivo package.json
  8. +
  9. +
    npm install express --save
    + +

    La sección de dependencias de su package.json ahora aparecerá al final del archivo package.json e incluirá Express.

    + +
    {
    +  "name": "myapp",
    +  "version": "1.0.0",
    +  "description": "",
    +  "main": "index.js",
    +  "scripts": {
    +    "test": "echo \"Error: no test specified\" && exit 1"
    +  },
    +  "author": "",
    +  "license": "ISC",
    +  "dependencies": {
    +    "express": "^4.16.3"
    +  }
    +}
    +
    +
  10. +
  11. Para usar la biblioteca, llame a la función require () como se muestra a continuación en su archivo index.js. +
    const express = require('express')
    +const app = express();
    +
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +});
    +
    +app.listen(8000, () => {
    +  console.log('Example app listening on port 8000!')
    +});
    +
    + +

    Este código muestra una aplicación web mínima "HelloWorld" Express. Esto importa el módulo "express" y lo usa para crear un servidor (app) que escucha las solicitudes HTTP en el puerto 8000 e imprime un mensaje en la consola que indica qué URL del navegador puede usar para probar el servidor. La función app.get () solo responde a las solicitudes HTTP GET con la ruta URL especificada ('/'), en este caso llamando a una función para enviar nuestro mensaje Hello World! .

    +
  12. +
  13. +

    Cree un archivo llamado index.js en la raíz del directorio de la aplicación "myapp" y dele el contenido que se muestra arriba.

    +
  14. +
  15. Puede iniciar el servidor llamando a node con el script en su símbolo del sistema: +
    >node index.js
    +Example app listening on port 8000
    +
    +
  16. +
  17. Navega a la URL (http://127.0.0.1:8000/). Sí todo esta funciona, el navegador simplemente debe mostrar la cadena de texto "Hello World".
  18. +
+ +

Dependencias de Desarrollo

+ +

Si una dependencia solo se usa durante el desarrollo, debe guardarla como una "dependencia de desarrollo" (para que los usuarios de su paquete no tengan que instalarla en producción). Por ejemplo, para usar la popular herramienta Linting JavaScript eslint llamaría a NPM como se muestra a continuación:

+ +
npm install eslint --save-dev
+ +
+
La siguiente entrada se agregaría al paquete.json de su aplicación:
+ +
+
+ +
  "devDependencies": {
+    "eslint": "^4.12.1"
+  }
+
+ +
+

Nota: "Linters" son herramientas que realizan análisis estáticos en el software para reconocer e informar la adhesión / no adhesión a algún conjunto de mejores prácticas de codificación.

+
+ +

Ejecutando tareas

+ +

Además de definir y buscar dependencias, también puede definir scripts con nombre en sus archivos package.json y llamar a NPM para ejecutarlos con el comando run-script. Este enfoque se usa comúnmente para automatizar las pruebas en ejecución y partes de la cadena de herramientas de desarrollo o construcción (por ejemplo, ejecutar herramientas para minimizar JavaScript, reducir imágenes, LINT/analizar su código, etc.).

+ +
+

Nota: Los ejecutadores de tareas como Gulp y Grunt también se pueden usar para ejecutar pruebas y otras herramientas externas.

+
+ +

Por ejemplo, para definir un script para ejecutar la dependencia de desarrollo de eslint que especificamos en la sección anterior, podríamos agregar el siguiente bloque de script a nuestro archivo package.json (suponiendo que el origen de nuestra aplicación esté en una carpeta /src/js):

+ +
"scripts": {
+  ...
+  "lint": "eslint src/js"
+  ...
+}
+
+ +

Para explicar un poco más, eslint src/js es un comando que podríamos ingresar en nuestra línea de terminal/linea de comandos para ejecutar eslint en archivos JavaScript contenidos en el directorio src/js dentro de nuestro directorio de aplicaciones. Incluir lo anterior dentro del archivo package.json de nuestra aplicación proporciona un acceso directo para este comando: lint.

+ +


+ Entonces podríamos ejecutar eslint usando NPM llamando a:

+ +
npm run-script lint
+# OR (using the alias)
+npm run lint
+
+ +
+
Es posible que este ejemplo no parezca más corto que el comando original, pero puede incluir comandos mucho más grandes dentro de sus scripts npm, incluidas cadenas de comandos múltiples. Puede identificar un solo script npm que ejecute todas sus pruebas a la vez.
+
+ +

Instalando Express Application Generator

+ +

La herramienta Express Application Generator genera un "esqueleto" de la aplicación Express. Instale el generador usando NPM como se muestra (el indicador -g instala la herramienta globalmente para que pueda llamarla desde cualquier lugar):

+ +
npm install express-generator -g
+ +

Para crear una aplicación Express llamada "helloworld" con la configuración predeterminada, navegue hasta donde desea crearla y ejecute la aplicación como se muestra:

+ +
express helloworld
+ +
+

Nota: También puede especificar la biblioteca de plantillas para usar y una serie de otras configuraciones. Use el comando --help para ver todas las opciones:

+ +
express --help
+
+
+ +

NPM creará la nueva aplicación Express en una subcarpeta de su ubicación actual, mostrando el progreso de la compilación en la consola. Al finalizar, la herramienta mostrará los comandos que necesita ingresar para instalar las dependencias de Node e iniciar la aplicación.

+ +
+

La nueva aplicación tendrá un archivo package.json en su directorio raíz. Puede abrir esto para ver qué dependencias están instaladas, incluidas Express y la biblioteca de plantillas Jade:

+ +
{
+  "name": "helloworld",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www"
+  },
+  "dependencies": {
+    "body-parser": "~1.18.2",
+    "cookie-parser": "~1.4.3",
+    "debug": "~2.6.9",
+    "express": "~4.15.5",
+    "jade": "~1.11.0",
+    "morgan": "~1.9.0",
+    "serve-favicon": "~2.4.5"
+  }
+}
+
+ +

Instale todas las dependencias para la aplicación helloworld usando NPM como se muestra:

+ +
cd helloworld
+npm install
+
+ +

Luego ejecute la aplicación (los comandos son ligeramente diferentes para Windows y Linux/macOS), como se muestra a continuación:

+ +
#  Ejecute helloworld en Windows con símbolo del sistema
+SET DEBUG=helloworld:* & npm start
+
+#  Ejecute helloworld en Windows con PowerShell
+SET DEBUG=helloworld:* | npm start
+
+#  Ejecute helloworld en Linux/macOS
+DEBUG=helloworld:* npm start
+
+ +

El comando DEBUG crea registros útiles, lo que resulta en una salida como la que se muestra a continuación.

+ +
>SET DEBUG=helloworld:* & npm start
+
+> helloworld@0.0.0 start D:\Github\expresstests\helloworld
+> node ./bin/www
+
+  helloworld:server Listening on port 3000 +0ms
+ +

Abra un navegador y navegue a http://127.0.0.1:3000/ para ver la página de bienvenida Express predeterminada.

+ +

Express - Generated App Default Screen

+ +

Hablaremos más sobre la aplicación generada cuando lleguemos al artículo sobre la generación de una aplicación esqueleto.

+ + + +

Resumen

+ +

Ahora tiene un entorno de desarrollo de Node en funcionamiento en su computadora que puede usarse para crear aplicaciones web Express. También ha visto cómo se puede usar NPM para importar Express en una aplicación, y también cómo puede crear aplicaciones usando la herramienta Express Application Generator y luego ejecutarlas.
+
+ En el siguiente artículo, comenzaremos a trabajar a través de un tutorial para crear una aplicación web completa utilizando este entorno y las herramientas asociadas.

+ +

Ver también

+ + + +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Introduction", "Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs")}}

+ +

In this module

+ + diff --git a/files/es/learn/server-side/express_nodejs/index.html b/files/es/learn/server-side/express_nodejs/index.html new file mode 100644 index 0000000000..2c224095c0 --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/index.html @@ -0,0 +1,76 @@ +--- +title: Express Web Framework (Node.js/JavaScript) +slug: Learn/Server-side/Express_Nodejs +tags: + - Aplicaciones Web + - Aprendizaje + - Express + - Express.js + - JavaScript + - Node + - Novato + - Programación del lado del Servidor + - introducción + - programacion +translation_of: Learn/Server-side/Express_Nodejs +--- +
{{LearnSidebar}}
+ +

Express es un framework web transigente, escrito en JavaScript y alojado dentro del entorno de ejecución NodeJS. El modulo explica algunos de los beneficios clave de este framework, como configurar tu entorno de desarrollo y como realizar tareas comunes en desarrollo y publicación web.

+ +

Prerequisitos

+ +

Antes de empezar con este módulo necesitaras entender los conceptos de programación web en el lado del servidor y los frameworks, de preferencia leyendo acerca de estos temas en nuestro modulo Primeros pasos en la programación web del lado del servidor. Un conocimiento general de conceptos de programación y JavaScript es altamente recomendado, pero no esencial para entender los conceptos básicos.

+ +
+

Nota : Esta web posee muchos recursos útiles para aprender JavaScript en el contexto del desarrollo en el lado del cliente:  JavaScript, Guía de JavaScript, JavaScript BásicoJavaScript (aprendizaje). El lenguaje JavaScript y sus conceptos son los mismos para el desarrollo en el lado del servidor en NodeJS y este material será relevante. NodeJS ofrece APIs adicionales para soportar funcionalidades que son útiles en entornos sin navegador web, por ejemplo para crear servidores HTTP y acceder al sistema de archivos, pero no soportan APIs de JavaScript para trabajar con el navegador y el DOM.

+ +

Esta guía proporciona información útil para trabajar con Node.js y Express, además hay numerosos y excelentes recursos en Internet y en libros - algunos de estos referenciados en Cómo empezar con Node.js (Inglés - StackOverflow) y ¿Cuáles son los mejores recursos para aprender Node.js? (Inglés - Quora).

+
+ +

Guías

+ +
+
Introducción a Express/Node 
+
En el primer artículo de Express respondemos las preguntas "¿Qué es Node?" y "¿Qué es Express?" y te daremos una visión general de qué hace especial al framework web Express. Destacaremos las principales caracteristicas, y mostraremos algunos de los bloques principales de una aplicación Express (aunque en este punto aún no tendrás un entorno de desarrollo para probarlo).
+
Preparando un entorno de desarrollo Node (Express)
+
Ahora que sabes para que sirve Express, te mostraremos como preparar y probar un entorno de desarrollo Node/Express en Windows, Linux (Ubuntu), y Mac OS X. Sin importar el sistema operativo que estes usando, este artículo te proporcionará lo que necesites para empezar a desarrollar aplicaciones Express.
+
Tutorial Express: la web de Librería local
+
El primer artículo en nuestra serie de tutoriales prácticos en los que se explica lo que aprenderás así como una breve introducción al proyecto de "Librería local", que será en el que trabajaremos y desarrollaremos a lo largo de la serie.
+
Tutorial Express 2: Creando el esqueleto de un sitio web 
+
Este artículo muestra cómo puede crear el "esqueleto" de un proyecto web, al cual podremos ir agregando nuestras rutas específicas para el sitio, plantillas/vistas, y bases de datos.
+
Tutorial Express  3: Usando una base de datos (con Mongoose)
+
Este artículo nos introducirá brevemente en las bases de datos para Node/Express. Entonces nos mostrara como podemos usar Mongoose para agregar acceso a una base de datos para el sitio web LocalLibrary. Explica como son declarados los objetos de esquema y modelos, los principales tipos para los campos, y validación básica. También mostrara brevemente algunas de las principales formas con las que puedes acceder a los modelos de datos.
+
Tutorial Express 4: Rutas y controladores
+
En este tutorial prepararemos las rutas (URL handling code) con un manejador de funciones "dummy" para todos los puntos de obtención de recursos que iremos a necesitar en nuestra web LocalLibrary. Al finalizar, tendremos una estructura modular para manejar nuestro código manejador de rutas, que podremos extender con funciones manejadoras reales en los artículos siguientes. También tendremos un muy buen entendimiento de cómo crear rutas modulares usando Express.
+
Tutorial Express 5: Mostrado datos de la librería
+
Ahora estamos listos para añadir paginas donde mostrar los libros de LocalLibrary y otros datos. Las paginas incluirán una página de inicio que muestre cuantos elementos tenemos de cada tipo de modelo, y páginas de lista y detalles para todos nuestros modelos. En el camino iremos ganando experiencia práctica en obtener elementos de la base de datos, y usando plantillas.
+
Tutorial Express 6: Trabajando con formularios
+
En este tutorial mostraremos como trabajar con formularios HTML en Express, usando Pug, y en particular como escribir formularios para crear, actualizar y borrar documentos en la base de datos.
+
Tutorial Express 7: Desplegando para producción
+
Ahora que has creado una increíble web llamada LocalLibrary, la querrás instalar en un servidor web público para que pueda acceder a ella el personal de la librería y los usuarios por Internet. Este artículo te ofrece una visión general de como deberías buscar un alojamiento para tu página web, y que necesitas para tener tu sitio listo para producción.
+
 
+
+ +

Ver también

+ +
+
Instalando LocalLibrary en PWS/Cloud Foundry
+
Este artículo nos da una demonstración práctica de cómo instalar LocalLibrary en la nube Pivotal Web Services PaaS — ésta es una alternativa, muy completa y de código libre, a Heroku, el servicio en la nube PaaS es usado en la parte 7 de este tutorial, listado más adelante. PWS/Cloud Foundry es un recurso digno de revisar si estás en busca de una alternativa a Heroku ( o cualquier otro servicio en la nube PaaS), o simplemente si tienes ganas de intentar algo diferente.
+
+ +

Añadiendo mas tutoriales

+ +
+

Este es el final de los tutoriales (por ahora). Si quisieras extenderlos, hay otros temas interesantes por tratar como:

+ + + +

Y por supuesto, ¡seria excelente tener una tarea de evaluación!

+
diff --git a/files/es/learn/server-side/express_nodejs/introduction/index.html b/files/es/learn/server-side/express_nodejs/introduction/index.html new file mode 100644 index 0000000000..d607c0dd0f --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/introduction/index.html @@ -0,0 +1,498 @@ +--- +title: Introducción a Express/Node +slug: Learn/Server-side/Express_Nodejs/Introduction +tags: + - Aprender + - Express + - MDN + - Node + - Servidor + - javascri + - lado del servidor + - nodejs +translation_of: Learn/Server-side/Express_Nodejs/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Aprendizaje/Lado-Servidor/Express_Nodejs/Ambiente-Desarrollo", "Aprendizaje/Lado-Servidor/Express_Nodejs")}}
+ +

En este primer articulo de Express resolveremos las preguntas "¿Qué es Node?" y "¿Qué es Express?", y te daremos una visión general de que hace especial al framework web "Express". Delinearemos las características principales, y te mostraremos algunos de los principales bloques de construcción de una aplicación en Express (aunque en este punto no tendrás todavía un entorno de desarrollo en que probarlo).

+ + + + + + + + + + + + +
Pre-requisitos: +

Conocimientos básicos de informática. Noción general sobre programación lado servidor de sitios web, y en particular los mecanismos de las interacciones cliente-servidor en sitios web.

+
Objetivo: +

Ganar familiaridad con lo que es Express y cómo encaja con Node, qué funcionalidad proporciona y los pilares de construcción de una aplicación Express.

+
+ +

¿Qué son Express y Node?

+ +

Node (o más correctamente: Node.js) es un entorno que trabaja en tiempo de ejecución, de código abierto, multi-plataforma, que permite a los desarrolladores crear toda clase de herramientas de lado servidor y aplicaciones en JavaScript. La ejecución en tiempo real está pensada para usarse fuera del contexto de un explorador web (es decir, ejecutarse directamente en una computadora o sistema operativo de servidor). Como tal, el entorno omite las APIs de JavaScript específicas del explorador web y añade soporte para APIs de sistema operativo más tradicionales que incluyen HTTP y bibliotecas de sistemas de ficheros.

+ +

Desde una perspectiva de desarrollo de servidor web, Node tiene un gran número de ventajas:

+ + + +

Puedes crear de forma sencilla un servidor web básico para responder cualquier petición simplemente usando el paquete HTTP de Node, como se muestra abajo. Este, creará un servidor y escuchará cualquier clase de peticiones en la URL http://127.0.0.1:8000/; cuando se reciba una petición, se responderá enviando en texto la respuesta: "Hola Mundo!".

+ +
// Se carga el módulo de HTTP
+var http = require("http");
+
+// Creación del servidor HTTP, y se define la escucha
+// de peticiones en el puerto 8000
+http.createServer(function(request, response) {
+
+   // Se define la cabecera HTTP, con el estado HTTP (OK: 200) y el tipo de contenido
+   response.writeHead(200, {'Content-Type': 'text/plain'});
+
+   // Se responde, en el cuerpo de la respuesta con el mensaje "Hello World"
+   response.end('Hola Mundo!\n');
+}).listen(8000);
+
+// Se escribe la URL para el acceso al servidor
+console.log('Servidor en la url http://127.0.0.1:8000/');
+ +

Otras tareas comunes de desarrollo web no están directamente soportadas por el mismo Node. Si quieres añadir el manejo específico de diferentes verbos HTTP (ej, GET, POST, DELETE, etc.), gestionar de forma separada las peticiones por medio de diferentes direcciones URL ("rutas"), servir ficheros estáticos o usar plantillas para crear la respuesta de forma dinámica, necesitarás escribir el código por tí mismo, o ¡puedes evitar reinventar la rueda usando un framework web!

+ +

Express es el framework web más popular de Node, y es la librería subyacente para un gran número de otros frameworks web de Node populares. Proporciona mecanismos para:

+ + + +

A pesar de que Express es en sí mismo bastante minimalista, los desarrolladores han creado paquetes de middleware compatibles para abordar casi cualquier problema de desarrollo web. Hay librerías para trabajar con cookies, sesiones, inicios de sesión de usuario, parámetros URL, datos POST, cabeceras de seguridad y muchos más. Puedes encontrar una lista de paquetes middleware mantenida por el equipo de Express en Express Middleware (junto con una lista de algunos de los paquetes más populares de terceros).

+ +
+

Nota: esta flexibilidad es una espada de doble filo. Hay paquetes de middleware para abordar casi cualquier problema o requerimiento, pero deducir cuáles son los paquetes adecuados a usar algunas veces puede ser un auténtico reto. Tampoco hay una "forma correcta" de estructurar una aplicación, y muchos ejemplos que puedes encontrar en la Internet no son óptimos, o sólo muestran una pequeña parte de lo que necesitas hacer para desarrollar una aplicación web.

+
+ +

¿Dónde comenzó?

+ +

Node fué lanzado inicialmente, sólo para Linux, en 2009. El gestor de paquetes NPM fué lanzado en 2010, y el soporte nativo para Windows fue añadido en 2012. La versión actual LTS (Long Term Suppport) es Node v12.18.0 mientras que la última versión es Node 14.4.0. Ésto es sólo una pequeña foto de una historia muy rica; profundiza en Wikipedia si quieres saber más).

+ +

Express fue lanzado inicialmente en Noviembre de 2010 y está ahora en la versión 4.17.1 de la API. Puedes comprobar en el changelog la información sobre cambios en la versión actual, y en GitHub notas de lanzamiento históricas más detalladas.

+ +

¿Qué popularidad tiene Node/Express?

+ +

La popularidad de un framework web es importante porque es un indicador de se continuará manteniendo y qué recursos tienen más probabilidad de estar disponibles en términos de documentación, librerías de extensiones y soporte técnico.

+ +

No existe una medida disponible de inmediato y definitiva de la popularidad de los frameworks de lado servidor (aunque sitios como Hot Frameworks intentan asesorar sobre popularidad usando mecanismos como contar para cada plataforma el número de preguntas sobre proyectos en GitHub y StackOverflow). Una pregunta mejor es si Node y Express son lo "suficientemente populares" para evitar los problemas de las plataformas menos populares. ¿Continúan evolucionando? ¿Puedes conseguir la ayuda que necesitas? ¿Hay alguna posibilidad de que consigas un trabajo remunerado si aprendes Express?

+ +

De acuerdo con el número de compañías de perfil alto que usan Express, el número de gente que contribuye al código base, y el número de gente que proporciona soporte tanto libre como pagado, podemos entonces decir que sí, !Express es un framework popular!

+ +

¿Es Express dogmático?

+ +

Los frameworks web frecuentemente se refieren a sí mismos como "dogmáticos" ("opinionated") o "no dogmáticos" ("unopinionated").

+ +

Los frameworks dogmáticos son aquellos que opinan acerca de la "manera correcta" de gestionar cualquier tarea en particular. Ofrecen soporte para el desarrollo rápido en un dominio en particular (resolver problemas de un tipo en particular) porque la manera correcta de hacer cualquier cosa está generalmente bien comprendida y bien documentada. Sin embargo pueden ser menos flexibles para resolver problemas fuera de su dominio principal, y tienden a ofrecer menos opciones para elegir qué componentes y enfoques pueden usarse.

+ +

Los framewoks no dogmáticos, en contraposición, tienen muchas menos restricciones sobre el modo mejor de unir componentes para alcanzar un objetivo, o incluso qué componentes deberían usarse. Hacen más fácil para los desarrolladores usar las herramientas más adecuadas para completar una tarea en particular, si bien al coste de que necesitas encontrar esos componentes por tí mismo.
+
+ Express es no dogmático, transigente. Puedes insertar casi cualquier middleware compatible que te guste dentro de la cadena de manejo de la petición, en casi cualquier orden que te apetezca. Puedes estructurar la app en un fichero o múltiples ficheros y usar cualquier estructura de directorios. ¡Algunas veces puedes sentir que tienes demasiadas opciones!

+ +

¿Cómo es el código para Express?

+ +

En sitios web o aplicaciones web dinámicas, que accedan a bases de datos, el servidor espera a recibir peticiones HTTP del navegador (o cliente). Cuando se recibe una petición, la aplicación determina cuál es la acción adecuada correspondiente, de acuerdo a la estructura de la URL y a la información (opcional) indicada en la petición con los métodos POSTGET. Dependiendo de la acción a realizar, puede que se necesite leer o escribir en la base de datos, o realizar otras acciones necesarias para atender la petición correctamente. La aplicación ha de responder al navegador, normalmente, creando una página HTML dinámicamente para él, en la que se muestre la información pedida, usualmente dentro de un elemento especifico para este fin, en una plantilla HTML.

+ +

Express posee métodos para especificar que función ha de ser llamada dependiendo del verbo HTTP usado en la petición (GET, POST, SET, etc.) y la estructura de la URL ("ruta"). También tiene los métodos para especificar que plantilla ("view") o gestor de visualización utilizar, donde están guardadas las plantillas de HTML que han de usarse  y como  generar la visualización adecuada para cada caso. El middleware de Express, puede usarse también para añadir funcionalidades para la gestión de cookies, sesiones y usuarios, mediante el uso de parámetros, en los métodos POST/GET.  Puede utilizarse además cualquier sistema de trabajo con bases de datos, que sea soportado por Node (Express no especifica ningún método preferido para trabajar con bases de datos). 

+ +

En las siguientes secciones, se explican algunos puntos comunes que se pueden encontrar cuando se trabaja con código de Node y Express.

+ +

Hola Mundo! - en Express

+ +

Primero consideremos el tradicional ejemplo de Hola Mundo! (se comentará cada parte a continuación).

+ +
+

Consejo: Si tiene Node y Express instalado (o piensa instalarlos posteriormente) puede guardar este código en un archivo llamado app.js y ejecutarlo posteriormente en la linea de comandos invocándolo mediante: node app.js

+
+ +
var express = require('express');
+var app = express();
+
+app.get('/', function(req, res) {
+  res.send('Hola Mundo!');
+});
+
+app.listen(3000, function() {
+  console.log('Aplicación ejemplo, escuchando el puerto 3000!');
+});
+
+ +

Las primeras dos líneas incluyen (mediante la orden require()) el módulo de Express y crean una aplicación de Express. Este elemento se denomina comúnmente app, y posee métodos para el enrutamiento de las peticiones HTTP, configuración del 'middleware', y visualización de las vistas de HTML, uso del motores de 'templates', y gestión de las configuraciones de las aplicaciones  que controlan la aplicación (por ejemplo el entorno, las definiciones para enrutado ... etcetera.)

+ +

Las líneas que siguen en el código (las tres líneas que comienzan con app.get) muestran una definición de ruta que se llamará cuando se reciba una petición  HTTP GET con una dirección ('/') relativa al directorio raíz. La función 'callback' coge una petición y una respuesta como argumentos, y ejecuta un send() en la respuesta, para enviar la cadena  de caracteres: "Hola Mundo!".

+ +

El bloque final de código, define y crea el servidor, escuchando el puerto 3000 e imprime un comentario en la consola. Cuando se está ejecutando el servidor, es posible ir hasta la dirección  localhost:3000  en un navegador, y ver como el servidor de este ejemplo devuelve el mensaje de respuesta.

+ +

Importando y creando módulos

+ +

Un modulo es una librería o archivo JavaScript que puede ser importado dentro de otro código utilizando la función require() de Node.  Por sí mismo, Express es un modulo,  como lo son el middleware y las librerías de bases de datos que se utilizan en las aplicaciones Express.

+ +

El código mostrado abajo, muestra como puede importarse un modulo con base a su nombre, como ejemplo se utiliza el  framework Express . Primero se invoca la función require(), indicando como parámetro el nombre del módulo o librería como una cadena ('express'),  posteriormente se invoca el objeto obtenido para crear una aplicación Express.

+ +

Posteriormente, se puede acceder a las propiedades y funciones del objeto Aplicación.

+ +
var express = require('express');
+var app = express();
+
+ +

También podemos crear nuestros propios módulos que puedan posteriormente ser importados de la misma manera.

+ +
+

Consejo:  Usted puede desear crear sus propios módulos, esto le permitirá organizar su código en partes más administrables; una aplicación que reside en un solo archivo es difícil de entender y manejar.

+ +

El utilizar módulos independientes también le permite administrar el espacio de nombres, de esta manera unicamente las variables que exporte explícitamente son importadas cuando utilice un módulo.

+
+ +

Para hacer que los objetos esten disponibles fuera de un modulo, solamente es necesario asignarlos al objeto exports. Por ejemplo, el modulo mostrado a continuación square.js  es un archivo que exporta los métodos area() y perimeter() :

+ +
exports.area = function(width) { return width * width; };
+exports.perimeter = function(width) { return 4 * width; };
+
+ +

Nosotros podemos importar este módulo utilizando la función require(), y entonces podremos invocar los métodos exportados de la siguiente manera:

+ +
// Utilizamos la función require() El nombre del archivo se ingresa sin la extensión (opcional) .js
+var square = require('./square');
+// invocamos el metodo area()
+console.log('El área de un cuadrado con lado de 4 es ' + square.area(4));
+ +
+

Nota: Usted también puede especificar una ruta absoluta a la  ubicación del módulo  (o un nombre como se realizó inicialmente). 

+
+ +

Si usted desea exportar completamente un objeto en una asignación en lugar de construir cada propiedad por separado, debe asignarlo al módulo module.exports como se muestra a continuación (también puede hacer esto al inicio de un constructor o de otra función.)

+ +
module.exports = {
+  area: function(width) {
+    return width * width;
+  },
+
+  perimeter: function(width) {
+    return 4 * width;
+  }
+};
+
+ +

Para más información acerca de módulos vea Modulos (Node API docs).

+ +

Usando APIs asíncronas

+ +

El código JavaScript usa frecuentemente APIs asíncronas antes que sincrónicas para operaciones que tomen algún tiempo en completarse. En una API sincrónica cada operación debe completarse antes de que la siguiente pueda comenzar. Por ejemplo, la siguiente función de registro es síncrona, y escribirá en orden el texto en la consola (Primero, Segundo).

+ +
console.log('Primero');
+console.log('Segundo');
+
+ +

En contraste, en una API asincrónica, la API comenzará una operación e inmediatamente retornará (antes de que la operación se complete). Una vez que la operación finalice, la API usará algún mecanismo para realizar operaciones adicionales. Por ejemplo, el código de abajo imprimirá "Segundo, Primero" porque aunque el método setTimeout() es llamado primero y retorna inmediatamente, la operación no se completa por varios segundos.

+ +
setTimeout(function() {
+   console.log('Primero');
+   }, 3000);
+console.log('Segundo');
+
+ +

Usar APIs asíncronas sin bloques es aun mas importante en Node que en el navegador, porque Node es un entorno de ejecución controlado por eventos de un solo hilo. "Un solo hilo" quiere decir que todas las peticiones al servidor son ejecutadas en el mismo hilo ( en vez de dividirse en procesos separados). Este modelo es extremadamente eficiente en términos de velocidad y recursos del servidor, pero eso significa que si alguna de sus funciones llama a métodos sincrónicos que tomen demasiado tiempo en completarse, bloquearan no solo la solicitud actual, sino también cualquier otra petición que este siendo manejada por tu aplicación web.

+ +

Hay muchas maneras para una API asincrónica de notificar a su aplicación que se ha completado. La manera mas común es registrar una función callback cuando usted invoca a una API asincrónica, la misma será llamada de vuelta cuando la operación se complete. Éste es el enfoque utilizado anteriormente.

+ +
+

Tip: Usar "callbacks" puede ser un poco enmarañado si usted tiene una secuencia de operaciones asíncronas dependientes que deben ser llevadas a cabo en orden, porque esto resulta en múltiples niveles de "callbacks" anidadas. Este problema es comúnmente conocido como "callback hell" (callback del infierno). Este problema puede ser reducido con buenas practicas de código (vea http://callbackhell.com/), usando un modulo como async, o incluso avanzando a características de ES6 como las promesas.

+
+ +
+

Nota: Una convención común para Node y Express es usar callbacks de error primero. En esta convención el primer valor en su función callback es un error, mientras que los argumentos subsecuentes contienen datos correctos. Hay una buena explicación de porque este enfoque es útil en este blog: The Node.js Way - Understanding Error-First Callbacks (fredkschott.com).

+
+ +

Creando manejadores de rutas

+ +

En nuestro ejemplo anterior de "Hola Mundo!" en Express (véase mas arriba), definimos una función (callback) manejadora de ruta para peticiones HTTP GET a la raíz del sitio ('/').

+ +
app.get('/', function(req, res) {
+  res.send('Hello World!');
+});
+
+ +

La función callback toma una petición y una respuesta como argumentos. En este caso el método simplemente llama a send() en la respuesta para retornar la cadena "Hello World!". Hay un número de otros métodos de respuesta para finalizar el ciclo de solicitud/respuesta, por ejemplo podrá llamar a res.json() para enviar una respuesta JSON o res.sendFile() para enviar un archivo.

+ +
+

JavaScript tip: Usted puede utilizar cualquier nombre que quiera para los argumentos en las funciones callback; cuando la callback es invocada el primer argumento siempre sera la petición y el segundo siempre sera la respuesta. Tiene sentido nombrarlos de manera que pueda identificar el objeto con el que esta trabajando en el cuerpo de la callback.

+
+ +

El objeto que representa una aplicación de Express, también posee métodos para definir los manejadores de rutas para el resto de los verbos HTTP: post(), put(), delete(), options(), trace(), copy(), lock(), mkcol(), move(), purge(), propfind(), proppatch(), unlock(), report(), mkactivity(), checkout(), merge(), m-search(), notify(), subscribe(), unsubscribe(), patch(), search(), y connect().

+ +

Hay un método general para definir las rutas:  app.all(), el cual será llamado en respuesta a cualquier método HTTP. Se usa para cargar funciones del middleware en una dirección particular para todos los métodos de peticiones. El siguiente ejemplo (de la documentación de Express) muestra el uso de los manejadores a  /secret  sin tener en cuenta el verbo HTTP utilizado (siempre que esté definido por el módulo http).

+ +
app.all('/secret', function(req, res, next) {
+  console.log('Accediendo a la seccion secreta ...');
+  next(); // pasa el control al siguiente manejador
+});
+ +

Las rutas le permiten igualar patrones particulares de caracteres en la URL, y extraer algunos valores de ella y pasarlos como parámetros al manejador de rutas (como atributo del objeto petición pasado como parámetro).

+ +

Usualmente es útil agrupar manejadores de rutas para una parte del sitio juntos y accederlos usando un prefijo de ruta en común. (Ej: un sitio con una Wiki podría tener todas las rutas relacionadas a dicha sección en un archivo y siendo accedidas con el prefijo de ruta /wiki/. En Express esto se logra usando el objeto express.Router. Ej: podemos crear nuestra ruta wiki en un módulo llamado wiki.js, y entonces exportar el objeto Router, como se muestra debajo:

+ +
// wiki.js - Modulo de rutas Wiki
+
+var express = require('express');
+var router = express.Router();
+
+// Home page route
+router.get('/', function(req, res) {
+  res.send('Página de inicio Wiki');
+});
+
+// About page route
+router.get('/about', function(req, res) {
+  res.send('Acerca de esta wiki');
+});
+
+module.exports = router;
+
+ +
+

Nota: Agregar rutas al objeto Router es como agregar rutas al objeto app ( como se vio anteriormente).

+
+ +

Para usar el router en nuestro archivo app principal, necesitamos require() el módulo de rutas (wiki.js), entonces llame use() en la aplicación Express para agregar el Router al software intermediario que maneja las rutas. Las dos rutas serán accesibles entonces desde /wiki/ y /wiki/about/.

+ +
var wiki = require('./wiki.js');
+// ...
+app.use('/wiki', wiki);
+ +

Le mostraremos mucho más sobre como trabajar con rutas, y en particular, acerca de como usar el Router, más adelante en la sección Rutas y controladores .

+ +

Usando middleware

+ +

El "middleware" es ampliamente utilizado en las aplicaciones de Express: desde tareas para servir archivos estáticos, a la gestión de errores o la compresión de las respuestas HTTP. Mientras las funciones de enrutamiento, con el objeto express.Router, se encargan del ciclo petición-respuesta, al gestionar la respuesta adecuada al cliente, las funciones de middleware normalmente realizan alguna operación al gestionar una petición o respuesta y a continuación llaman a la siguiente función en la "pila", que puede ser otra función de middleware  u otra función de enrutamiento. El orden en el que las funciones de middleware son llamadas depende del desarrollador de la aplicación.

+ +
+

Nota: El middleware puede realizar cualquier operación: hacer cambios a una petición, ejecutar código, realizar cambios a la petición o al objeto pedido, puede también finalizar el ciclo de petición-respuesta. Si no finaliza el ciclo debe llamar a la función next() para pasar el control de la ejecución a la siguiente función del middleware ( o a la petición quedaría esperando una respuesta ... ). 

+
+ +

La mayoría de las aplicaciones usan middleware desarrollado por terceras partes, para simplificar funciones habituales en el desarrollo web, como puede ser: gestión de cookies, sesiones, autentificado de usuarios, peticiones POST  y datos en JSON, registros de eventos, etc. Puede encontrar en el siguiente enlace una  lista de middleware mantenido por el equipo de Express (que también incluye otros paquetes populares de terceras partes). Las librerías de Express están disponibles con la aplicación NPM (Node Package Manager).

+ +

Para usar estas colecciones, primero ha de instalar la aplicación usando NPM. Por ejemplo para instalar el registro de peticiones HTTP morgan, se haría con el comando Bash:  

+ +
$ npm install morgan
+
+ +

Entonces podría llamar a la función use() en un objeto de aplicación Express para utilizar este middleware a su aplicación. 

+ +
var express = require('express');
+var logger = require('morgan');
+var app = express();
+app.use(logger('dev'));
+...
+ +
+

Note: Las funciones Middleware y routing son llamadas en el orden que son declaradas. Para algunos middleware el orden es importante (por ejemplo si el middleware de sesion depende del middleware de cookie, entonces el manejador de cookie tiene que ser llamado antes). Casi siempre es el caso que el middleware es llamado antes de configurar las rutas, o tu manejador de rutas no tendra acceso a la funcionalidad agregada por tu middleware.

+
+ +

Tu puedes escribir tu propia funcion middleware, y si quieres hacerlo así (solo para crear código de manejo de error). La única diferencia entre una función middleware y un callback manejador de rutas es que las funciones middleware tienen un tercer argumento next, cuyas funciones  middleware son esperadas para llamarlas si ellas no completan el ciclo request (cuando la función midleware es llamada, esta contiene la próxima función que debe ser llamada).

+ +

Puede agregar una función middleware a la cadenan de procesamiento con cualquier app.use()app.add(), dependiendo de si quiere aplicar el middleware a todas las respuestas o a respuestas con un verbo particular HTTP (GET, POST, etc). Usted especifica rutas, lo mismo en ambos casos, aunque la ruta es opcional cuando llama app.use().

+ +

El ejemplo de abajo muestra como puede agregar la función middleware usando ambos métodos, y con/sin una ruta.

+ +
var express = require('express');
+var app = express();
+
+// An example middleware function
+var a_middleware_function = function(req, res, next) {
+  // ... perform some operations
+  next(); // Call next() so Express will call the next middleware function in the chain.
+}
+
+// Function added with use() for all routes and verbs
+app.use(a_middleware_function);
+
+// Function added with use() for a specific route
+app.use('/someroute', a_middleware_function);
+
+// A middleware function added for a specific HTTP verb and route
+app.get('/', a_middleware_function);
+
+app.listen(3000);
+ +
+

JavaScript Tip: Arriba declaramos la función middleware separadamente y la configuramos como el callback. En nuestra función previous manejadora de ruta declaramos la función callback cuando esta fué usada. En JavaScript, cuealquer aproximación es valida.

+
+ +

La documentación Express tiene mucha mas documentación excelente acerca del uso y escritura de middleware Express.

+ +

Sirviendo archivos estáticos

+ +

Puede utilizar el middleware express.static para servir archivos estáticos, incluyendo sus imagenes, CSS y JavaScript (static() es la única función  middleware que es actualmente parte de Express). Por ejemplo, podria utilizar la linea de abajo para servir imágenes, archivos CSS, y archivos JavaScript desde un directorio nombrado 'public' al mismo nivel desde donde llama a node:

+ +
app.use(express.static('public'));
+
+ +

Cualesquiere archivos en el directorio público son servidos al agregar su nombre de archivo (relativo a la ubicación del directorio "público" ) de la ubicación URL. Por ejemplo:

+ +
http://localhost:3000/images/dog.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/about.html
+
+ +

Puede llamar static() multiples ocasiones a servir multiples directorios. Si un archivo no puede ser encontrado por una función middleware entonces este simplemente será pasado en la subsequente middleware (el orden en que el middleware está basado en  su orden de declaración).

+ +
app.use(express.static('public'));
+app.use(express.static('media'));
+
+ +

Tambien puede crear un prefijo virtual para sus URLs estáticas, aun más teniendo los archivos agregados en la ubicación URL. Por ejemplo, aqui especificamos a mount path tal que los archivos son bajados con el prefijo "/media":

+ +
app.use('/media', express.static('public'));
+
+ +

Ahora, puede bajar los archivos que estan en el directorio publico del path con prefijo /media.

+ +
http://localhost:3000/media/images/dog.jpg
+http://localhost:3000/media/video/cat.mp4
+http://localhost:3000/media/cry.mp3
+
+ +

Para más información, ver Sirviendo archivos estáticos en Express.

+ +

Manejando errores

+ +

Los errores majejados por una o más funciones especiales middleware que tienen cuatro argumentos, en lugar de las usuales tres: (err, req, res, next). For example:

+ +
app.use(function(err, req, res, next) {
+  console.error(err.stack);
+  res.status(500).send('Something broke!');
+});
+
+ +

Estas pueden devolver cualquier contenido, pero deben ser llamadas despues de todas las otras app.use() llamadas de rutas tal que ellas son las últimas middleware en el proceso de manejo de request!

+ +

Express viene con un manejador de error integrado, el que se ocupa de error remanente que pudiera ser encontrado en la app. Esta función middleware manejador de error esta agregada al final del stack de funciones middleware. Si pasa un error a next() y no lo maneja en un manejador de error, este sera manejado por el manejador de error integrado; el error sera escrito en el cliente con el rastreo de pila.

+ +
+

Note: El rastreo de pila no esta incluido en el ambiente de producción. Para ejecutarlo en modo de producción necesita configurar la variable de ambiente NODE_ENV to 'production'.

+
+ +
+

Note: HTTP404 y otros codigos de estatus de "error" no son tratados como errores. Si quiere manejar estos, puede agregar una función middleware para hacerlo. Para mas información vea las FAQ.

+
+ +

Para mayor información vea Manejo de error (Docs. Express).

+ +

Usando Bases de datos

+ +

Las apps de Express pueden usar cualquier mecanismo de bases de datos suportadas por Node (Express en sí mismo no define ningúna conducta/requerimiento specifico adicional para administración de bases de datos). Hay muchas opciones, incluyendo PostgreSQL, MySQL, Redis, SQLite, MongoDB, etc.

+ +

Con el propósito de usar éste, debe primero instalar el manejador de bases de datos utilizando NPM. Por ejemplo, para instalar el manejador para el popular NoSQL MongoDB querría utilizar el comando:

+ +
$ npm install mongodb
+
+ +

La base de datos por si misma puede ser instalada localmente o en un servidor de la nube. En su codigo Express requiere el manejador, conectarse a la base de datos, y entonces ejecutar operaciones crear, leer, actualizar, y borrar (CLAB). }El ejemplo de abajo (de la documentación Express documentation) muestra como puede encontrar registros en la colección "mamiferos" usando MongoDB.

+ +
var MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
+  if (err) throw err;
+
+  db.collection('mammals').find().toArray(function (err, result) {
+    if (err) throw err;
+
+    console.log(result);
+  });
+});
+ +

Otra aproximación popular es acceder a su base de datos indirectamente, via an Mapeo Objeto Relacional ("MOR"). En esta aproximación usted define sus datos como "objetos" o "modelos" y el MOR mapea estos a través del deliniamiento basico de la base de datos. Esta aproximación tiene el beneficio de que como un desrrollador puede continuar pensando en términos de objetos de JavaScript mas que en semántica de bases de datos, y en esto hay un lugar obvio para ejecutar la validación y chequeo de entrada de datos. Hablaremos más de bases de datos en un artículo posterior.

+ +

Para más información ver Integracion de Bases de Datos (docs Express ).

+ +

Renderización de data (vistas)

+ +

El Motor de plantilla (referido como "motor de vistas" por Express) le permite definir la estructura de documento de salida en una plantilla, usando marcadores de posición para datos que seran llenados cuando una pagina es generada. Las plantillas son utilizadas generalmete para crear HTML, pero tambien pueden crear otros tipos de documentos. Express tiene soporte para  numerosos motores de plantillas, y hay una util comparación de los motores más populares aquí: Comparando Motores de Plantillas de JavaScript: Jade, Mustache, Dust and More.

+ +

En su código de configuración de su aplicación usted configura el motor de plantillas para usar y su localización Express podiría buscar plantillas usando las configuraciones de 'vistas' y 'motores de vistas', mostrado abajo (tendría también que instalar el paquete conteniendo su librería de plantillas!)

+ +
var express = require('express');
+var app = express();
+
+// Set directory to contain the templates ('views')
+app.set('views', path.join(__dirname, 'views'));
+
+// Set view engine to use, in this case 'some_template_engine_name'
+app.set('view engine', 'some_template_engine_name');
+
+ +

La apariencia de la plantilla dependera de qué motor use. Asumiendo que tiene un archivo de plantillas nombrado "index.<template_extension>" este contiene placeholders para variables de datos nombradas 'title' y "message", podría llamar Response.render() en una función manejadora de rutas para crear y enviar la HTML response:

+ +
app.get('/', function(req, res) {
+  res.render('index', { title: 'About dogs', message: 'Dogs rock!' });
+});
+ +

Para más información vea Usando motores de plantillas con Express (docs Express ).

+ +

Estructura de Archivos

+ +

Express no hace asunciones en términos de estructura o que componentes usted usa. Rutas, vistas, archivos estáticos, y otras lógicas de aplicación específica puede vivir en cualquier número de archivos con cualquier estructura de directorio. Mientras que esto es perfectamente posible, se puede tener toda la aplicación en un solo archivo, en Express, tipicamente esto tiene sentido al desplegar su aplicacion dentro de archivos basados en función (e.g. administracion de cuentas, blogs, tableros de discusion) y dominio de problema arquitectonico (e.g. modelo, vista or controlador si tu pasas a estar usando una arquitectura MVC).

+ +

En un tópico posterior usaremos el Generador de Aplicaciones Express Application Generator, el que crea un esquelo de una app modular que podemos facilmente extender para crear aplicaciones web.

+ + + +

Resumen

+ +

¡Felicitaciones, ha completado el primer paso en su viaje Express/Node! Ahora debes comprender los principales beneficios de Express y Node, y más o menos cómo se verían las partes principales de una aplicación Express (rutas, middleware, manejo de errores y plantillas). ¡También debe comprender que con Express como un framework unopinionated, la forma en que une estas partes y las bibliotecas que usa dependen en gran medida de usted!
+
+ Por supuesto, Express es deliberadamente un un
framework de aplicaciones web muy ligero, por lo que gran parte de sus beneficios y potencial proviene de bibliotecas y características de terceros. Lo veremos con más detalle en los siguientes artículos. En nuestro próximo artículo, veremos cómo configurar un entorno de desarrollo de Node, para que pueda comenzar a ver código de Express en acción.

+ +

Ver también

+ + + +
{{NextMenu("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs")}}
+ +

En este modulo

+ + diff --git a/files/es/learn/server-side/express_nodejs/mongoose/index.html b/files/es/learn/server-side/express_nodejs/mongoose/index.html new file mode 100644 index 0000000000..f5701c468a --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/mongoose/index.html @@ -0,0 +1,801 @@ +--- +title: 'Express Tutorial 3: Utilizando bases de datos (con Mongoose)' +slug: Learn/Server-side/Express_Nodejs/mongoose +translation_of: Learn/Server-side/Express_Nodejs/mongoose +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs")}}
+ +

Este artículo introduce brevemente las bases de datos así como su uso en aplicaciones Node/Express. Despues, profundiza en el uso específico de Mongoose en el proyecto LocalLibrary. Explica como se declaran y utilizan los esquemas modelo-objeto, los principales campos de datos y su validación básica. También muestra brevemente algunas de las muchas formas para acceder y modificar los datos.

+ + + + + + + + + + + + +
PrerequisitosExpress Tutorial 2: Creando un esqueleto web
Objetivo:Ser capaz de crear, diseñar y utilizar bases de datos en Node/Express utilizando Mongoose
+ +

Overview

+ +

Library staff will use the Local Library website to store information about books and borrowers, while library members will use it to browse and search for books, find out whether there are any copies available, and then reserve or borrow them. In order to store and retrieve information efficiently, we will store it in a database.

+ +

Las aplicaciones Express pueden utilizar diferentes bases de datos, y existen diferentes aproximaciones que se pueden utilizar para realizar operaciones CRUD (Create, Read, Update and Delete). Este tutorial proporciona una vista general sobre algunas de las opciones disponibles, para a continuación mostrar en detalle los mecanismos elegidos en particular.

+ +

What databases can I use?

+ +

Express apps can use any database supported by Node (Express itself doesn't define any specific additional behaviour/requirements for database management). There are many popular options, including PostgreSQL, MySQL, Redis, SQLite, and MongoDB.

+ +

When choosing a database, you should consider things like time-to-productivity/learning curve, performance, ease of replication/backup, cost, community support, etc. While there is no single "best" database, almost any of the popular solutions should be more than acceptable for a small-to-medium-sized site like our Local Library.

+ +

For more information on the options see: Database integration (Express docs).

+ +

What is the best way to interact with a database?

+ +

There are two approaches for interacting with a database: 

+ + + +

The very best performance can be gained by using SQL, or whatever query language is supported by the database. ODM's are often slower because they use translation code to map between objects and the database format, which may not use the most efficient database queries (this is particularly true if the ODM supports different database backends, and must make greater compromises in terms of what database features are supported).

+ +

The benefit of using an ORM is that programmers can continue to think in terms of JavaScript objects rather than database semantics — this is particularly true if you need to work with different databases (on either the same or different websites). They also provide an obvious place to perform validation and checking of data.

+ +
+

Tip:  Using ODM/ORMs often results in lower costs for development and maintenance! Unless you're very familiar with the native query language or performance is paramount, you should strongly consider using an ODM.

+
+ +

What ORM/ODM should I use?

+ +

There are many ODM/ORM solutions available on the NPM package manager site (check out the odm and orm tags for a subset!).

+ +

A few solutions that were popular at the time of writing are:

+ + + +

As a general rule you should consider both the features provided and the "community activity" (downloads, contributions, bug reports, quality of documentation, etc.) when selecting a solution. At time of writing Mongoose is by far the most popular ORM, and is a reasonable choice if you're using MongoDB for your database.

+ +

Using Mongoose and MongoDb for the LocalLibrary

+ +

For the Local Library example (and the rest of this topic) we're going to use the Mongoose ODM to access our library data. Mongoose acts as a front end to MongoDB, an open source NoSQL database that uses a document-oriented data model. A “collection” of “documents”, in a MongoDB database, is analogous to a “table” of “rows” in a relational database.

+ +

This ODM and database combination is extremely popular in the Node community, partially because the document storage and query system looks very much like JSON, and is hence familiar to JavaScript developers.

+ +
+

Tip: You don't need to know MongoDB in order to use Mongoose, although parts of the Mongoose documentation are easier to use and understand if you are already familiar with MongoDB.

+
+ +

The rest of this tutorial shows how to define and access the Mongoose schema and models for the LocalLibrary website example.

+ +

Designing the LocalLibrary models

+ +

Before you jump in and start coding the models, it's worth taking a few minutes to think about what data we need to store and the relationships between the different objects.

+ +

We know that we need to store information about books (title, summary, author, genre, ISBN) and that we might have multiple copies available (with globally unique ids, availability statuses, etc.). We might need to store more information about the author than just their name, and there might be multiple authors with the same or similar names. We want to be able to sort information based on book title, author, genre, and category.

+ +

When designing your models it makes sense to have separate models for every "object" (group of related information). In this case the obvious objects are books, book instances, and authors.

+ +

You might also want to use models to represent selection-list options (e.g. like a drop down list of choices), rather than hard coding the choices into the website itself — this is recommended when all the options aren't known up front or may change. The obvious candidate for a model of this type is the book genre (e.g. Science Fiction, French Poetry, etc.)

+ +

Once we've decided on our models and fields, we need to think about the relationships between them.

+ +

With that in mind, the UML association diagram below shows the models we'll define in this case (as boxes). As discussed above, we've created models for book (the generic details of the book), book instance (status of specific physical copies of the book available in the system), and author. We have also decided to have a model for genre, so that values can be created dynamically. We've decided not to have a model for the BookInstance:status — we will hard code the acceptable values because we don't expect these to change. Within each of the boxes you can see the model name, the field names and types, and also the methods and their return types.

+ +

The diagram also shows the relationships between the models, including their multiplicities. The multiplicities are the numbers on the diagram showing the numbers (maximum and minimum) of each model that may be present in the relationship. For example, the connecting line between the boxes shows that Book and a Genre are related. The numbers close to the Book model show that a Genre must have zero or more Book (as many as you like), while the numbers on the other end of the line next to the Genre show that it can have zero or more associated genre.

+ +
+

Note: As discussed in our Mongoose primer below it is often better to have the field that defines the relationship between the documents/models in just one model (you can still find the reverse relationship by searching for the associated _id in the other model). Below we have chosen to define the relationship between Book/Genre and Book/Author in the Book schema, and the relationship between the Book/BookInstance in the BookInstance Schema. This choice was somewhat arbitrary — we could equally well have had the field in the other schema.

+
+ +

Mongoose Library Model  with correct cardinality

+ +
+

Note: The next section provides a basic primer explaining how models are defined and used. As you read it, consider how we will construct each of the models in the diagram above.

+
+ +

Mongoose primer

+ +

This section provides an overview of how to connect Mongoose to a MongoDB database, how to define a schema and a model, and how to make basic queries. 

+ +
+

Note: This primer is "heavily influenced" by the Mongoose quick start on npm and the official documentation.

+
+ +

Installing Mongoose and MongoDB

+ +

Mongoose is installed in your project (package.json) like any other dependency — using NPM. To install it, use the following command inside your project folder:

+ +
npm install mongoose
+
+ +

Installing Mongoose adds all its dependencies, including the MongoDB database driver, but it does not install MongoDB itself. If you want to install a MongoDB server then you can download installers from here for various operating systems and install it locally. You can also use cloud-based MongoDB instances.

+ +
+

Note: For this tutorial we'll be using the mLab cloud-based database as a service sandbox tier to provide the database. This is suitable for development, and makes sense for the tutorial because it makes "installation" operating system independent (database-as-a-service is also one approach you might well use for your production database).

+
+ +

Connecting to MongoDB

+ +

Mongoose requires a connection to a MongoDB database. You can require() and connect to a locally hosted database with mongoose.connect(), as shown below.

+ +
//Import the mongoose module
+var mongoose = require('mongoose');
+
+//Set up default mongoose connection
+var mongoDB = 'mongodb://127.0.0.1/my_database';
+mongoose.connect(mongoDB);
+// Get Mongoose to use the global promise library
+mongoose.Promise = global.Promise;
+//Get the default connection
+var db = mongoose.connection;
+
+//Bind connection to error event (to get notification of connection errors)
+db.on('error', console.error.bind(console, 'MongoDB connection error:'));
+ +

You can get the default Connection object with mongoose.connection. Once connected, the open event is fired on the Connection instance.

+ +
+

Tip: If you need to create additional connections you can use mongoose.createConnection(). This takes the same form of database URI (with host, database, port, options etc.) as connect() and returns a Connection object).

+
+ +

Defining and creating models

+ +

Models are defined using the Schema interface. The Schema allows you to define the fields stored in each document along with their validation requirements and default values. In addition, you can define static and instance helper methods to make it easier to work with your data types, and also virtual properties that you can use like any other field, but which aren't actually stored in the database (we'll discuss a bit further below).

+ +

Schemas are then "compiled" into models using the mongoose.model() method. Once you have a model you can use it to find, create, update, and delete objects of the given type.

+ +
+

Note: Each model maps to a collection of documents in the MongoDB database. The documents will contain the fields/schema types defined in the model Schema.

+
+ +

Defining schemas

+ +

The code fragment below shows how you might define a simple schema. First you require() mongoose, then use the Schema constructor to create a new schema instance, defining the various fields inside it in the constructor's object parameter.

+ +
//Require Mongoose
+var mongoose = require('mongoose');
+
+//Define a schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+    a_string: String,
+    a_date: Date
+});
+
+ +

In the case above we just have two fields, a string and a date. In the next sections we will show some of the other field types, validation, and other methods.

+ +

Creating a model

+ +

Models are created from schemas using the mongoose.model() method:

+ +
// Define schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+    a_string: String,
+    a_date: Date
+});
+
+// Compile model from schema
+var SomeModel = mongoose.model('SomeModel', SomeModelSchema );
+ +

The first argument is the singular name of the collection that will be created for your model (Mongoose will create the database collection for the above model SomeModel above), and the second argument is the schema you want to use in creating the model.

+ +
+

Note: Once you've defined your model classes you can use them to create, update, or delete records, and to run queries to get all records or particular subsets of records. We'll show you how to do this in the Using models section, and when we create our views.

+
+ +

Tipos de esquema (campos)

+ +

Un esquema puede tener un número de campos arbitrario  — cada uno representa un campo en los documentos almacenados en MongoDB. A continuación se muestra un ejemplo de esquema con varios de los tipos de campos más comunes y cómo se declaran.

+ +
var schema = new Schema(
+{
+  name: String,
+  binary: Buffer,
+  living: Boolean,
+  updated: { type: Date, default: Date.now },
+  age: { type: Number, min: 18, max: 65, required: true },
+  mixed: Schema.Types.Mixed,
+  _someId: Schema.Types.ObjectId,
+  array: [],
+  ofString: [String], // You can also have an array of each of the other types too.
+  nested: { stuff: { type: String, lowercase: true, trim: true } }
+})
+ +

Most of the SchemaTypes (the descriptors after “type:” or after field names) are self explanatory. The exceptions are:

+ + + +

The code also shows both ways of declaring a field:

+ + + +

For more information about options see SchemaTypes (Mongoose docs).

+ +

Validation

+ +

Mongoose provides built-in and custom validators, and synchronous and asynchronous validators. It allows you to specify both the acceptable range or values and the error message for validation failure in all cases.

+ +

The built-in validators include:

+ + + +

The example below (slightly modified from the Mongoose documents) shows how you can specify some of the validator types and error messages:

+ +

+    var breakfastSchema = new Schema({
+      eggs: {
+        type: Number,
+        min: [6, 'Too few eggs'],
+        max: 12,
+        required: [true, 'Why no eggs?']
+      },
+      drink: {
+        type: String,
+        enum: ['Coffee', 'Tea', 'Water',]
+      }
+    });
+
+ +

For complete information on field validation see Validation (Mongoose docs).

+ +

Virtual properties

+ +

Virtual properties are document properties that you can get and set but that do not get persisted to MongoDB. The getters are useful for formatting or combining fields, while setters are useful for de-composing a single value into multiple values for storage. The example in the documentation constructs (and deconstructs) a full name virtual property from a first and last name field, which is easier and cleaner than constructing a full name every time one is used in a template.

+ +
+

Note: We will use a virtual property in the library to define a unique URL for each model record using a path and the record's _id value.

+
+ +

For more information see Virtuals (Mongoose documentation).

+ +

Methods and query helpers

+ +

A schema can also have instance methods, static methods, and query helpers. The instance and static methods are similar, but with the obvious difference that an instance method is associated with a particular record and has access to the current object. Query helpers allow you to extend mongoose's chainable query builder API (for example, allowing you to add a query "byName" in addition to the find(), findOne() and findById() methods).

+ +

Using models

+ +

Once you've created a schema you can use it to create models. The model represents a collection of documents in the database that you can search, while the model's instances represent individual documents that you can save and retrieve.

+ +

We provide a brief overview below. For more information see: Models (Mongoose docs).

+ +

Creating and modifying documents

+ +

To create a record you can define an instance of the model and then call save(). The examples below assume SomeModel is a model (with a single field "name") that we have created from our schema.

+ +
// Create an instance of model SomeModel
+var awesome_instance = new SomeModel({ name: 'awesome' });
+
+// Save the new model instance, passing a callback
+awesome_instance.save(function (err) {
+  if (err) return handleError(err);
+  // saved!
+});
+
+ +

Creation of records (along with updates, deletes, and queries) are asynchronous operations — you supply a callback that is called when the operation completes. The API uses the error-first argument convention, so the first argument for the callback will always be an error value (or null). If the API returns some result, this will be provided as the second argument.

+ +

You can also use create() to define the model instance at the same time as you save it. The callback will return an error for the first argument and the newly-created model instance for the second argument.

+ +
SomeModel.create({ name: 'also_awesome' }, function (err, awesome_instance) {
+  if (err) return handleError(err);
+  // saved!
+});
+ +

Every model has an associated connection (this will be the default connection when you use mongoose.model()). You create a new connection and call .model() on it to create the documents on a different database.

+ +

You can access the fields in this new record using the dot syntax, and change the values. You have to call save() or update() to store modified values back to the database.

+ +
// Access model field values using dot notation
+console.log(awesome_instance.name); //should log 'also_awesome'
+
+// Change record by modifying the fields, then calling save().
+awesome_instance.name="New cool name";
+awesome_instance.save(function (err) {
+   if (err) return handleError(err); // saved!
+   });
+
+ +

Searching for records

+ +

You can search for records using query methods, specifying the query conditions as a JSON document. The code fragment below shows how you might find all athletes in a database that play tennis, returning just the fields for athlete name and age. Here we just specify one matching field (sport) but you can add more criteria, specify regular expression criteria, or remove the conditions altogether to return all athletes.

+ +
var Athlete = mongoose.model('Athlete', yourSchema);
+
+// find all athletes who play tennis, selecting the 'name' and 'age' fields
+Athlete.find({ 'sport': 'Tennis' }, 'name age', function (err, athletes) {
+  if (err) return handleError(err);
+  // 'athletes' contains the list of athletes that match the criteria.
+})
+ +

If you specify a callback, as shown above, the query will execute immediately. The callback will be invoked when the search completes.

+ +
+

Note: All callbacks in Mongoose use the pattern callback(error, result). If an error occurs executing the query, the error parameter will contain an error document, and result will be null. If the query is successful, the error parameter will be null, and the result will be populated with the results of the query.

+
+ +

If you don't specify a callback then the API will return a variable of type Query. You can use this query object to build up your query and then execute it (with a callback) later using the exec() method.

+ +
// find all athletes that play tennis
+var query = Athlete.find({ 'sport': 'Tennis' });
+
+// selecting the 'name' and 'age' fields
+query.select('name age');
+
+// limit our results to 5 items
+query.limit(5);
+
+// sort by age
+query.sort({ age: -1 });
+
+// execute the query at a later time
+query.exec(function (err, athletes) {
+  if (err) return handleError(err);
+  // athletes contains an ordered list of 5 athletes who play Tennis
+})
+ +

Above we've defined the query conditions in the find() method. We can also do this using a where() function, and we can chain all the parts of our query together using the dot operator (.) rather than adding them separately. The code fragment below is the same as our query above, with an additional condition for the age.

+ +
Athlete.
+  find().
+  where('sport').equals('Tennis').
+  where('age').gt(17).lt(50).  //Additional where query
+  limit(5).
+  sort({ age: -1 }).
+  select('name age').
+  exec(callback); // where callback is the name of our callback function.
+ +

The find() method gets all matching records, but often you just want to get one match. The following methods query for a single record:

+ + + +
+

Note: There is also a count() method that you can use to get the number of items that match conditions. This is useful if you want to perform a count without actually fetching the records.

+
+ +

There is a lot more you can do with queries. For more information see: Queries (Mongoose docs).

+ + + +

You can create references from one document/model instance to another using the ObjectId schema field, or from one document to many using an array of ObjectIds. The field stores the id of the related model. If you need the actual content of the associated document, you can use the populate() method in a query to replace the id with the actual data.

+ +

For example, the following schema defines authors and stories. Each author can have multiple stories, which we represent as an array of ObjectId. Each story can have a single author. The "ref" (highlighted in bold below) tells the schema which model can be assigned to this field.

+ +
var mongoose = require('mongoose')
+  , Schema = mongoose.Schema
+
+var authorSchema = Schema({
+  name    : String,
+  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
+});
+
+var storySchema = Schema({
+  author : { type: Schema.Types.ObjectId, ref: 'Author' },
+  title    : String
+});
+
+var Story  = mongoose.model('Story', storySchema);
+var Author = mongoose.model('Author', authorSchema);
+ +

We can save our references to the related document by assigning the _id value. Below we create an author, then a story, and assign the author id to our stories author field.

+ +
var bob = new Author({ name: 'Bob Smith' });
+
+bob.save(function (err) {
+  if (err) return handleError(err);
+
+  //Bob now exists, so lets create a story
+  var story = new Story({
+    title: "Bob goes sledding",
+    author: bob._id    // assign the _id from the our author Bob. This ID is created by default!
+  });
+
+  story.save(function (err) {
+    if (err) return handleError(err);
+    // Bob now has his story
+  });
+});
+ +

Our story document now has an author referenced by the author document's ID. In order to get the author information in our story results we use populate(), as shown below.

+ +
Story
+.findOne({ title: 'Bob goes sledding' })
+.populate('author') //This populates the author id with actual author information!
+.exec(function (err, story) {
+  if (err) return handleError(err);
+  console.log('The author is %s', story.author.name);
+  // prints "The author is Bob Smith"
+});
+ +
+

Note: Astute readers will have noted that we added an author to our story, but we didn't do anything to add our story to our author's stories array. How then can we get all stories by a particular author? One way would be to add our author to the stories array, but this would result in us having two places where the information relating authors and stories needs to be maintained.

+ +

A better way is to get the _id of our author, then use find() to search for this in the author field across all stories.

+ +
Story
+.find({ author : bob._id })
+.exec(function (err, stories) {
+  if (err) return handleError(err);
+  // returns all stories that have Bob's id as their author.
+});
+
+
+ +

This is almost everything you need to know about working with related items for this tutorial. For more detailed information see Population (Mongoose docs).

+ +

One schema/model per file

+ +

While you can create schemas and models using any file structure you like, we highly recommend defining each model schema in its own module (file), exporting the method to create the model. This is shown below:

+ +
// File: ./models/somemodel.js
+
+//Require Mongoose
+var mongoose = require('mongoose');
+
+//Define a schema
+var Schema = mongoose.Schema;
+
+var SomeModelSchema = new Schema({
+    a_string          : String,
+    a_date            : Date,
+});
+
+//Export function to create "SomeModel" model class
+module.exports = mongoose.model('SomeModel', SomeModelSchema );
+ +

You can then require and use the model immediately in other files. Below we show how you might use it to get all instances of the model.

+ +
//Create a SomeModel model just by requiring the module
+var SomeModel = require('../models/somemodel')
+
+// Use the SomeModel object (model) to find all SomeModel records
+SomeModel.find(callback_function);
+ +

Setting up the MongoDB database

+ +

Now that we understand something of what Mongoose can do and how we want to design our models, it's time to start work on the LocalLibrary website. The very first thing we want to do is set up a MongoDb database that we can use to store our library data.

+ +

For this tutorial we're going to use mLab's free cloud-hosted "sandbox" database. This database tier is not considered suitable for production websites because it has no redundancy, but it is great for development and prototyping. We're using it here because it is free and easy to set up, and because mLab is a popular database as a service vendor that you might reasonably choose for your production database (other popular choices at the time of writing include Compose, ScaleGrid and MongoDB Atlas).

+ +
+

Note: If you prefer you can set up a MongoDb database locally by downloading and installing the appropriate binaries for your system. The rest of the instructions in this article would be similar, except for the database URL you would specify when connecting.

+
+ +

You will first need to create an account with mLab (this is free, and just requires that you enter basic contact details and acknowledge their terms of service). 

+ +

After logging in, you'll be taken to the home screen:

+ +
    +
  1. Click Create New in the MongoDB Deployments section.
  2. +
  3. This will open the Cloud Provider Selection screen.
    + MLab - screen for new deployment
    + +
      +
    • Select the SANDBOX (Free) plan from the Plan Type section. 
    • +
    • Select any provider from the Cloud Provider section. Different providers offer different regions (displayed below the selected plan type).
    • +
    • Click the Continue button.
    • +
    +
  4. +
  5. This will open the Select Region screen. +

    Select new region screen

    + +
      +
    • +

      Select the region closest to you and then Continue.

      +
    • +
    +
  6. +
  7. +

    This will open the Final Details screen.
    + New deployment database name

    + +
      +
    • +

      Enter the name for the new database as local_library and then select Continue.

      +
    • +
    +
  8. +
  9. +

    This will open the Order Confirmation screen.
    + Order confirmation screen

    + +
      +
    • +

      Click Submit Order to create the database.

      +
    • +
    +
  10. +
  11. +

    You will be returned to the home screen. Click on the new database you just created to open its details screen. As you can see the database has no collections (data).
    + mLab - Database details screen
    +  
    + The URL that you need to use to access your database is displayed on the form above (shown for this database circled above). In order to use this you need to create a database user that you can specify in the URL.

    +
  12. +
  13. Click the Users tab and select the Add database user button.
  14. +
  15. Enter a username and password (twice), and then press Create. Do not select Make read only.
    +
  16. +
+ +

You have now created the database, and have an URL (with username and password) that can be used to access it. This will look something like: mongodb://your_user_namer:your_password@ds119748.mlab.com:19748/local_library.

+ +

Install Mongoose

+ +

Open a command prompt and navigate to the directory where you created your skeleton Local Library website. Enter the following command to install Mongoose (and its dependencies) and add it to your package.json file, unless you have already done so when reading the Mongoose Primer above.

+ +
npm install mongoose
+
+ +

Connect to MongoDB

+ +

Open /app.js (in the root of your project) and copy the following text below where you declare the Express application object (after the line var app = express();). Replace the database url string ('insert_your_database_url_here') with the location URL representing your own database (i.e. using the information from mLab).

+ +
//Set up mongoose connection
+var mongoose = require('mongoose');
+var mongoDB = 'insert_your_database_url_here';
+mongoose.connect(mongoDB);
+mongoose.Promise = global.Promise;
+var db = mongoose.connection;
+db.on('error', console.error.bind(console, 'MongoDB connection error:'));
+ +

As discussed in the Mongoose primer above, this code creates the default connection to the database and binds to the error event (so that errors will be printed to the console). 

+ +

Defining the LocalLibrary Schema

+ +

We will define a separate module for each model, as discussed above. Start by creating a folder for our models in the project root (/models) and then create separate files for each of the models:

+ +
/express-locallibrary-tutorial  //the project root
+  /models
+    author.js
+    book.js
+    bookinstance.js
+    genre.js
+
+ +

Author model

+ +

Copy the Author schema code shown below and paste it into your ./models/author.js file. The scheme defines an author has having String SchemaTypes for the first and family names, that are required and have a maximum of 100 characters, and Date fields for the date of birth and death.

+ +
var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var AuthorSchema = new Schema(
+  {
+    first_name: {type: String, required: true, max: 100},
+    family_name: {type: String, required: true, max: 100},
+    date_of_birth: {type: Date},
+    date_of_death: {type: Date},
+  }
+);
+
+// Virtual for author's full name
+AuthorSchema
+.virtual('name')
+.get(function () {
+  return this.family_name + ', ' + this.first_name;
+});
+
+// Virtual for author's lifespan
+AuthorSchema
+.virtual('lifespan')
+.get(function () {
+  return (this.date_of_death.getYear() - this.date_of_birth.getYear()).toString();
+});
+
+// Virtual for author's URL
+AuthorSchema
+.virtual('url')
+.get(function () {
+  return '/catalog/author/' + this._id;
+});
+
+//Export model
+module.exports = mongoose.model('Author', AuthorSchema);
+
+
+ +

We've also declared a virtual for the AuthorSchema named "url" that returns the absolute URL required to get a particular instance of the model — we'll use the property in our templates whenever we need to get a link to a particular author.

+ +
+

Note: Declaring our URLs as a virtual in the schema is a good idea because then the URL for an item only ever needs to be changed in one place.
+ At this point, a link using this URL wouldn't work, because we haven't got any routes handling code for individual model instances. We'll set those up in a later article!

+
+ +

At the end of the module we export the model.

+ +

Book model

+ +

Copy the Book schema code shown below and paste it into your ./models/book.js file. Most of this is similar to the author model — we've declared a schema with a number of string fields and a virtual for getting the URL of specific book records, and we've exported the model.

+ +
var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var BookSchema = new Schema(
+  {
+    title: {type: String, required: true},
+    author: {type: Schema.Types.ObjectId, ref: 'Author', required: true},
+    summary: {type: String, required: true},
+    isbn: {type: String, required: true},
+    genre: [{type: Schema.Types.ObjectId, ref: 'Genre'}]
+  }
+);
+
+// Virtual for book's URL
+BookSchema
+.virtual('url')
+.get(function () {
+  return '/catalog/book/' + this._id;
+});
+
+//Export model
+module.exports = mongoose.model('Book', BookSchema);
+
+ +

The main difference here is that we've created two references to other models:

+ + + +

BookInstance model

+ +

Finally, copy the BookInstance schema code shown below and paste it into your ./models/bookinstance.js file. The BookInstance represents a specific copy of a book that someone might borrow, and includes information about whether the copy is available or on what date it is expected back, "imprint" or version details.

+ +
var mongoose = require('mongoose');
+
+var Schema = mongoose.Schema;
+
+var BookInstanceSchema = new Schema(
+  {
+    book: { type: Schema.Types.ObjectId, ref: 'Book', required: true }, //reference to the associated book
+    imprint: {type: String, required: true},
+    status: {type: String, required: true, enum: ['Available', 'Maintenance', 'Loaned', 'Reserved'], default: 'Maintenance'},
+    due_back: {type: Date, default: Date.now}
+  }
+);
+
+// Virtual for bookinstance's URL
+BookInstanceSchema
+.virtual('url')
+.get(function () {
+  return '/catalog/bookinstance/' + this._id;
+});
+
+//Export model
+module.exports = mongoose.model('BookInstance', BookInstanceSchema);
+ +

The new things we show here are the field options:

+ + + +

Everything else should be familiar from our previous schema.

+ +

Genre model - challenge!

+ +

Open your ./models/genre.js file and create a schema for storing genres (the category of book, e.g. whether it is fiction or non-fiction, romance or military history, etc).

+ +

The definition will be very similar to the other models:

+ + + +

Testing — create some items

+ +

That's it. We now have all models for the site set up!

+ +

In order to test the models (and to create some example books and other items that we can use in our next articles) we'll now run an independent script to create items of each type:

+ +
    +
  1. Download (or otherwise create) the file populatedb.js inside your express-locallibrary-tutorial directory (in the same level as package.json). + +
    +

    Note: You don't need to know how populatedb.js works; it just adds sample data into the database.

    +
    +
  2. +
  3. Enter the following commands in the project root to install the async module that is required by the script (we'll discuss this in later tutorials, ) +
    npm install async
    +
  4. +
  5. Run the script using node in your command prompt, passing in the URL of your MongoDB database (the same one you replaced the insert_your_database_url_here placeholder with, inside app.js earlier): +
    node populatedb <your mongodb url>​​​​
    +
  6. +
  7. The script should run through to completion, displaying items as it creates them in the terminal.
  8. +
+ +
+

Tip: Go to your database on mLab. You should now be able to drill down into individual collections of Books, Authors, Genres and BookInstances, and check out individual documents.

+
+ +

Summary

+ +

In this article, we've learned a bit about databases and ORMs on Node/Express, and a lot about how Mongoose schema and models are defined. We then used this information to design and implement Book, BookInstance, Author and Genre models for the LocalLibrary website.

+ +

Last of all we tested our models by creating a number of instances (using a standalone script). In the next article we'll look at creating some pages to display these objects.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs")}}

+ +

 

+ +

In this module

+ + + +

 

diff --git a/files/es/learn/server-side/express_nodejs/skeleton_website/index.html b/files/es/learn/server-side/express_nodejs/skeleton_website/index.html new file mode 100644 index 0000000000..b829e52665 --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/skeleton_website/index.html @@ -0,0 +1,502 @@ +--- +title: 'Express Tutorial Part 2: Creating a skeleton website' +slug: Learn/Server-side/Express_Nodejs/skeleton_website +translation_of: Learn/Server-side/Express_Nodejs/skeleton_website +--- +
{{LearnSidebar}}
+ +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}

+ +

Este segundo artículo de nuestro Tutorial Express muestra cómo puede crear un "esqueleto" para un proyecto de sitio web que luego puede completar con rutas, plantillas/vistas, y llamadas a base de datos especifícas del sitio.

+ + + + + + + + + + + + +
Prerequisitos:Configurar un entorno de desarrollo de Node. Revise el Tutorial Express.
Objetivo:Poder empezar sus nuevos proyectos web usando el Generador de Aplicaciones Express.
+ +

Visión General

+ +

Este artículo muestra cómo puede crear un sitio web "esqueleto"  usando la herramienta Generador de Aplicaciones Express, que luego puede completar con rutas, vistas/plantillas, y llamadas a base de datos especifícas del sitio.  En este caso usaremos la herramienta para crear el framework para nuestro  website Local Library, al que luego agregaremos todo el código que el sitio necesite.  El proceso es extremadamente simple, requiriendo sólo que se invoque el generador en la línea de comandos con un nombre para el nuevo proyecto, opcionalmente especificando también el motor de plantillas y el generador de CSS a utilizar.

+ +

Las siguientes secciones muestran como puede llamar al generador de aplicaciones, y proporcionan una pequeña explicación sobre las diferentes opciones para vistas y CSS.  También explicaremos como está estructurado el esqueleto del sitio web.  Al final, mostraremos como puede ejecutar el sitio web para verificar que funciona.

+ +
+

Nota: El Generador de Aplicaciones Express no es el único generador para aplicaciones Express, y el proyecto generado no es la única forma viable para estructurar sus archivos y directorios.  El sitio generado, sin embargo, tiene una estructura modular que es fácil de extender y comprender.  Para informacion sobre una mínima  aplicación Express, vea el Ejemplo Hello world  (Express docs).

+
+ +

Usando el generador de aplicaciones

+ +

Ya debe haber instalado el generador como parte de Configurar un entorno de desarrollo de Node. Como un rápido recordatorio, la herramienta generador se instala para todos los sitios usando el manejador de paquetes NPM, como se muestra:

+ +
npm install express-generator -g
+ +

El generador tiene un número de opciones, las cuales puede observar en la línea de comandos usando el comando --help (o bien  -h):

+ +
> express --help
+
+  Usage: express [options] [dir]
+
+  Options:
+
+    -h, --help           output usage information
+        --version        output the version number
+    -e, --ejs            add ejs engine support
+        --pug            add pug engine support
+        --hbs            add handlebars engine support
+    -H, --hogan          add hogan.js engine support
+    -v, --view <engine>  add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
+    -c, --css <engine>   add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
+        --git            add .gitignore
+    -f, --force          force on non-empty directory
+
+ +

Simplemente puede especificar express para crear un proyecto dentro del directorio actual usando el motor de plantillas Jade y CSS plano (si especifica un nombre de directorio entonces el proyecto será creado en un subdirectorio con ese nombre).

+ +
express
+ +

También puede seleccionar el motor de plantillas para las vistas usando  --view y/o un motor generador de CSS usando --css.

+ +
+

Nota: Las otras opciones para elegir motores de plantillas (e.g. --hogan, --ejs, --hbs etc.) están descontinuadas. Use --view (o bien -v)!

+
+ +

¿Cuál motor de vistas debo usar?

+ +

El Generador de Aplicaciones Express le permite configurar un número de populares motores de plantillas, incluyendo EJS, Hbs, Pug (Jade), Twig, y Vash, aunque si no se especifica una opcion de vista, selecciona Jade por defecto. Express puede soportar un gran número de motores de plantillas aquí una lista.

+ +
+

Nota: Si quiere usar un motor de plantillas que no es soportado por el generador entonces vea el artículo  Usando motores de plantillas con Express (Express docs) y la documentación de su motor de plantillas.

+
+ +

Generalmente hablando debe seleccionar un motor de plantillas que le brinde toda la funcionalidad que necesite y le permita ser productivo rápidamente  — o en otras palabras, en la misma forma en que selecciona cualquier otro componente.  Alguna de las cosas a considerar cuando se comparan motores de plantillas:

+ + + +
+

Tip: En Internet hay muchos recursos que le ayudarán a comparar diferentes opciones. 

+
+ +

Para este proyecto usaremos el motor de plantillas Pug (este es el  recientemente renombrado motor Jade), ya que es de los más populares lenguajes de plantillas Express/JavaScript y es soportado por el generador por defecto.

+ +

¿Cuál motor de hojas de estilo CSS debería usar?

+ +

El Generador de Aplicaciones Express le permite crear un proyecto que puede usar los más comunes motores  de  hojas  de estilos CSS: LESS, SASS, Compass, Stylus.

+ +
+

Nota: CSS tiene  algunas  limitaciones  que  dificultan ciertas  tareas. Los  motores  de hojas de estilos  CSS le permiten usar una sintaxis más poderosa para definir su  CSS, y luego compilar la definición en texto  plano para  su uso  en los  navegadores .

+
+ +

Como los  motores  de plantillas, debería usar el motor CSS que le permita a su  equipo  ser más  productivo.  Para este proyecto  usaremos CSS ordinario (opción  por defecto) ya que nuestros requerimientos no son lo suficientemente complicados para justificar el uso de un motor CSS. 

+ +

¿Cuál base de datos  debería usar?

+ +

El código generado no usa o incluye ninguna base de datos.  Las aplicaciones Express pueden  usar cualquier mecanismo de bases  de datos soportado por  Node (Express por si  mismo no define ningún comportamiento o requerimiento para el manejo de bases de datos).

+ +

Discutiremos la integración con una base de datos en un posterior artículo.

+ +

Creando el proyecto

+ +

Para el ejemplo que vamos a crear la app Local Library, crearemos un proyecto llamado express-locallibrary-tutorial usando la librería de plantillas Pug y ningún motor CSS.

+ +

Primero navegue a donde quiera crear el proyecto y luego ejecute el Generador de Aplicaciones Express en la línea  de comandos como se muestra:

+ +
express express-locallibrary-tutorial --view=pug
+
+ +

El generador creará (y listará) los archivos del proyecto.

+ +
   create : express-locallibrary-tutorial
+   create : express-locallibrary-tutorial/package.json
+   create : express-locallibrary-tutorial/app.js
+   create : express-locallibrary-tutorial/public/images
+   create : express-locallibrary-tutorial/public
+   create : express-locallibrary-tutorial/public/stylesheets
+   create : express-locallibrary-tutorial/public/stylesheets/style.css
+   create : express-locallibrary-tutorial/public/javascripts
+   create : express-locallibrary-tutorial/routes
+   create : express-locallibrary-tutorial/routes/index.js
+   create : express-locallibrary-tutorial/routes/users.js
+   create : express-locallibrary-tutorial/views
+   create : express-locallibrary-tutorial/views/index.pug
+   create : express-locallibrary-tutorial/views/layout.pug
+   create : express-locallibrary-tutorial/views/error.pug
+   create : express-locallibrary-tutorial/bin
+   create : express-locallibrary-tutorial/bin/www
+
+   install dependencies:
+     > cd express-locallibrary-tutorial && npm install
+
+   run the app:
+     > SET DEBUG=express-locallibrary-tutorial:* & npm start
+ +

Al final de la lista el generador mostrará instrucciones sobre como instalar las dependencias necesarias (mostradas en el archivo package.json) y luego como ejecutar la aplicación (las instrucciones anteriores son para windows; en Linux/macOS serán ligeramente diferentes).

+ +

Ejecutando el esqueleto del sitio web

+ +

En este punto tenemos un esqueleto completo de nuestro proyecto.  El sitio web  no hace mucho actualmente, pero es bueno ejecutarlo para ver como funciona.

+ +
    +
  1. Primero instale las dependencias (el comando install recuperará todas las dependencias listadas e el archivo package.json del proyecto). + +
    cd express-locallibrary-tutorial
    +npm install
    +
  2. +
  3. Luego ejecute la aplicación. +
      +
    • En Windows, use este  comando: +
      SET DEBUG=express-locallibrary-tutorial:* & npm start
      +
    • +
    • En macOS o Linux, use este comando: +
      DEBUG=express-locallibrary-tutorial:* npm start
      +
      +
    • +
    +
  4. +
  5. Luego carge en su navegador http://localhost:3000/ para acceder a la aplicación.
  6. +
+ +

Debería ver una página parecida a esta:

+ +

Browser for default Express app generator website

+ +

Tiene una aplicación Express funcional, ejecutandose en localhost:3000.

+ +
+

Nota: También podría ejecutar la app usando el comando npm start. Especificado la variable DEBUG como se muestra habilita el logging/debugging por consola. Por ejemplo, cuando visite la página mostrada arriba verá la información de depuración como esta:

+ +
>SET DEBUG=express-locallibrary-tutorial:* & npm start
+
+> express-locallibrary-tutorial@0.0.0 start D:\express-locallibrary-tutorial
+> node ./bin/www
+
+  express-locallibrary-tutorial:server Listening on port 3000 +0ms
+GET / 200 288.474 ms - 170
+GET /stylesheets/style.css 200 5.799 ms - 111
+GET /favicon.ico 404 34.134 ms - 1335
+
+ +

Habilite el reinicio del servidor cuando los archivos sean modificados

+ +

Cualquier cambio que le haga a su sitio web Express no será visible hasta que reinicie el servidor. Rapidamente, tener que detener y reiniciar el servidor cada vez que hacemos un cambio, se vuelve irritante, así que es beneficioso tomarse un tiempo y automátizar el reinicio del servidor cuando sea necesario.

+ +

Una de las herramientas más sencillas para este propósito es nodemon. Éste usualmente se instala globalmente (ya que es una "herramienta"), pero aquí lo instalaremos y usaremos localmente como una dependencia de desarrollo, así cualquier desarrollador que esté trabajando con el proyecto lo obtendrá automáticamente cuando instale la aplicación. Use el siguiente comando en el directorio raíz del esqueleto del proyecto:

+ +
npm install --save-dev nodemon
+ +

Si abre el archivo package.json de su proyecto verá una nueva sección con esta dependencia:

+ +
  "devDependencies": {
+    "nodemon": "^1.14.11"
+  }
+
+ +

Debido a que la herramienta no fue instalada globalmente no podemos ejecutarla desde la línea de comandos (a menos que la agreguemos a la ruta) pero podemos llamarla desde un script NPM porque NPM sabe todo sobre los paquetes instalados. Busque la sección scripts de su package.json. Inicialmente contendrá una línea, la cual comienza con "start". Actualicela colocando una coma al final de la línea, y agregue la línea "devstart" mostrada abajo:

+ +
  "scripts": {
+    "start": "node ./bin/www",
+    "devstart": "nodemon ./bin/www"
+  },
+
+ +

Ahora podemos iniciar el servidor casi exactamente como antes, pero especificando el comando devstart:

+ + + +
+

Nota: Ahora si modifica cualquier archivo del proyecto el servidor se reiniciará  (o lo puede reiniciar rs en la consola de comandos en cualquier momento). Aún necesitará recargar el navegador para refrescar la página.

+ +

Ahora tendremos que llamar "npm run <nombre del script>" en vez de npm start, porque "start" es actualmente un comando NPM que es mapeado al nombre del script. Podríamos haber reemplazado el comando en el script start pero sólo queremos usar nodemon durante el desarrollo, así que tiene sentido crear un nuevo script para este comando.

+
+ +

El proyecto generado

+ +

Observemos el proyecto que hemos creado.

+ +

Estructura del directorio

+ +

El proyecto generado, ahora que ha instalado las dependencias, tiene la siguiente estructura de archivos (los archivos son los elementos que no están precedidos con "/"). El archivo package.json define las dependencias de la aplicación y otra información. También define un script de inicio que es el punto de entrada de la aplicación,  el archivo JavaScript /bin/www. Éste establece algunos de los manejadores de error de la aplicación y luego carga el archivo app.js para que haga el resto del trabajo.  Las rutas se almacenan en módulos separados en el directorio /routes. las plantillas se almacenan en el directorio /views.

+ +
/express-locallibrary-tutorial
+    app.js
+    /bin
+        www
+    package.json
+    /node_modules
+        [about 4,500 subdirectories and files]
+    /public
+        /images
+        /javascripts
+        /stylesheets
+            style.css
+    /routes
+        index.jsusers.js
+    /views
+        error.pug
+        index.puglayout.pug
+
+
+ +

Las siguientes secciones describen los archivos con más detalle. 

+ +

package.json

+ +

El archivo package.json define las dependencias de la aplicación y otra información: 

+ +
{
+  "name": "express-locallibrary-tutorial",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www",
+    "devstart": "nodemon ./bin/www"
+  },
+  "dependencies": {
+    "body-parser": "~1.18.2",
+    "cookie-parser": "~1.4.3",
+    "debug": "~2.6.9",
+    "express": "~4.16.2",
+    "morgan": "~1.9.0",
+    "pug": "~2.0.0-rc.4",
+    "serve-favicon": "~2.4.5"
+  },
+  "devDependencies": {
+    "nodemon": "^1.14.11"
+  }
+}
+
+ +

Las dependencias incluyen el paquete express y los paquetes para el motor de plantillas elegido (pug). Adicionalmente, tenemos los siguientes paquetes que son útiles en muchas aplicaciones web: 

+ + + +

La sección de scripts define un script de "start", que es lo que invocamos cuando llamamos a npm start para iniciar el servidor. Desde la definición del script, puede ver que esto realmente inicia el archivo JavaScript ./bin/www con node. También define un script "devstart", que invocamos cuando llamamos a npm run devstart en su lugar. Esto inicia el mismo archivo ./bin/www, pero con nodemon en lugar de node.

+ +
  "scripts": {
+    "start": "node ./bin/www",
+    "devstart": "nodemon ./bin/www"
+  },
+
+ +

www file

+ +

El archivo /bin/www es el punto de entrada de la aplicación. Lo primero que hace es require () el punto de entrada de la aplicación "real" (app.js, en la raíz del proyecto) que configura y devuelve el objeto de la aplicación express ().

+ +
#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var app = require('../app');
+
+ +
+

Note: require() es una función de node global que se usa para importar módulos en el archivo actual. Aquí especificamos el módulo app.js utilizando una ruta relativa y omitiendo la extensión de archivo opcional (.js).

+
+ +

El resto del código en este archivo configura un servidor HTTP de node con la aplicación configurada en un puerto específico (definido en una variable de entorno o 3000 si la variable no está definida), y comienza a escuchar e informar errores y conexiones del servidor. Por ahora no necesita saber nada más sobre el código (todo en este archivo es "repetitivo"), pero siéntase libre de revisarlo si está interesado.

+ +

app.js

+ +

Este archivo crea un objeto de aplicación rápida (aplicación denominada, por convención), configura la aplicación con varias configuraciones y middleware, y luego exporta la aplicación desde el módulo. El siguiente código muestra solo las partes del archivo que crean y exportan el objeto de la aplicación:

+ +
var express = require('express');
+var app = express();
+...
+module.exports = app;
+
+ +

De vuelta en el archivo de punto de entrada www anterior, es este objeto module.exports que se proporciona al llamante cuando se importa este archivo.

+ +

Permite trabajar a través del archivo app.js en detalle. Primero importamos algunas bibliotecas de node útiles en el archivo usando require (), incluyendo express, serve-favicon, morgan, cookie-parser y body-parser que previamente descargamos para nuestra aplicación usando NPM; y path, que es una biblioteca central de nodos para analizar rutas de archivos y directorios.

+ +
var express = require('express');
+var path = require('path');
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var cookieParser = require('cookie-parser');
+var bodyParser = require('body-parser');
+
+ +

Luego require () modules de nuestro directorio de rutas. Estos modules/files contienen código para manejar conjuntos particulares de "routes" relacionadas (rutas URL). Cuando extendemos la aplicación esqueleto, por ejemplo, para enumerar todos los libros de la biblioteca, agregaremos un nuevo archivo para tratar las rutas relacionadas con los libros.

+ +
var index = require('./routes/index');
+var users = require('./routes/users');
+
+ +
+

Note: En este punto, acabamos de importar el módulo; aún no hemos utilizado sus rutas (esto sucede un poco más abajo en el archivo).

+
+ +

Next we create the app object using our imported express module, and then use it to set up the view (template) engine. There are two parts to setting up the engine. First we set the 'views' value to specify the folder where the templates will be stored (in this case the sub folder /views). Then we set the 'view engine' value to specify the template library (in this case "pug").

+ +
var app = express();
+
+// view engine setup
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+
+ +

The next set of functions call app.use() to add the middleware libraries into the request handling chain. In addition to the 3rd party libraries we imported previously, we use the express.static middleware to get Express to serve all the static files in the /public directory in the project root.

+ +
// uncomment after placing your favicon in /public
+//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
+app.use(logger('dev'));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(cookieParser());
+app.use(express.static(path.join(__dirname, 'public')));
+
+ +

Now that all the other middleware is set up, we add our (previously imported) route-handling code to the request handling chain. The imported code will define particular routes for the different parts of the site:

+ +
app.use('/', index);
+app.use('/users', users);
+
+ +
+

Note: The paths specified above ('/' and '/users') are treated as a prefix to routes defined in the imported files. So for example if the imported users module defines a route for /profile, you would access that route at /users/profile. We'll talk more about routes in a later article.

+
+ +

The last middleware in the file adds handler methods for errors and HTTP 404 responses.

+ +
// catch 404 and forward to error handler
+app.use(function(req, res, next) {
+  var err = new Error('Not Found');
+  err.status = 404;
+  next(err);
+});
+
+// error handler
+app.use(function(err, req, res, next) {
+  // set locals, only providing error in development
+  res.locals.message = err.message;
+  res.locals.error = req.app.get('env') === 'development' ? err : {};
+
+  // render the error page
+  res.status(err.status || 500);
+  res.render('error');
+});
+
+ +

The Express application object (app) is now fully configured. The last step is to add it to the module exports (this is what allows it to be imported by /bin/www).

+ +
module.exports = app;
+ +

Routes

+ +

The route file /routes/users.js is shown below (route files share a similar structure, so we don't need to also show index.js). First it loads the express module, and uses it to get an express.Router object. Then it specifies a route on that object, and lastly exports the router from the module (this is what allows the file to be imported into app.js).

+ +
var express = require('express');
+var router = express.Router();
+
+/* GET users listing. */
+router.get('/', function(req, res, next) {
+  res.send('respond with a resource');
+});
+
+module.exports = router;
+
+ +

The route defines a callback that will be invoked whenever an HTTP GET request with the correct pattern is detected. The matching pattern is the route specified when the module is imported ('/users') plus whatever is defined in this file ('/'). In other words, this route will be used when an URL of /users/ is received.

+ +
+

Tip: Try this out by running the server with node and visiting the URL in your browser: http://localhost:3000/users/. You should see a message: 'respond with a resource'.

+
+ +

One thing of interest above is that the callback function has the third argument 'next', and is hence a middleware function rather than a simple route callback. While the code doesn't currently use the next argument, it may be useful in the future if you want to add multiple route handlers to the '/' route path.

+ +

Views (templates)

+ +

The views (templates) are stored in the /views directory (as specified in app.js) and are given the file extension .pug. The method Response.render() is used to render a specified template along with the values of named variables passed in an object, and then send the result as a response. In the code below from /routes/index.js you can see how that route renders a response using the template "index" passing the template variable "title".

+ +
/* GET home page. */
+router.get('/', function(req, res) {
+  res.render('index', { title: 'Express' });
+});
+
+ +

The corresponding template for the above route is given below (index.pug). We'll talk more about the syntax later. All you need to know for now is that the title variable (with value 'Express') is inserted where specified in the template.

+ +
extends layout
+
+block content
+  h1= title
+  p Welcome to #{title}
+
+ +

Challenge yourself

+ +

Create a new route in /routes/users.js that will display the text "You're so cool" at URL /users/cool/. Test it by running the server and visiting http://localhost:3000/users/cool/ in your browser

+ + + +

Summary

+ +

You have now created a skeleton website project for the Local Library and verified that it runs using node. Most important, you also understand how the project is structured, so you have a good idea where we need to make changes to add routes and views for our local library.

+ +

Next we'll start modifying the skeleton so that works as a library website.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Tutorial_local_library_website", "Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs")}}

+ +

In this module

+ + diff --git a/files/es/learn/server-side/express_nodejs/tutorial_local_library_website/index.html b/files/es/learn/server-side/express_nodejs/tutorial_local_library_website/index.html new file mode 100644 index 0000000000..825cc0c8c0 --- /dev/null +++ b/files/es/learn/server-side/express_nodejs/tutorial_local_library_website/index.html @@ -0,0 +1,83 @@ +--- +title: 'Express Tutorial: The Local Library website' +slug: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website +translation_of: Learn/Server-side/Express_Nodejs/Tutorial_local_library_website +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}
+ +

El primer artículo de nuestra serie de tutoriales prácticos explica lo que aprenderá y proporciona una descripción general del sitio web de ejemplo de la "biblioteca local" en el que trabajaremos y evolucionaremos en artículos posteriores.

+ + + + + + + + + + + + +
Prerequisitos:Leer la Introducción a Express. Para los siguientes artículos, también deberá haber configurado un entorno de desarrollo de Node
Objetivo:Presentar la aplicación de ejemplo utilizada en este tutorial, y permitir a los lectores comprender qué temas se tratarán.
+ +

Visión General

+ +

Bienvenido al tutorial de MDN "Biblioteca Local" Express (Node), en el cual desarrollamos un sitio web que podría usarse para administrar el catálogo de una biblioteca local.
+
+ En esta serie de artículos tutoriales, usted:

+ + + +

Ya se ha aprendido sobre algunos de estos temas y se ha referido brevemente a otros. Al final de la serie de tutoriales, debe saber lo suficiente como para desarrollar aplicaciones Express simples usted mismo.

+ +

The LocalLibrary website

+ +

LocalLibrary es el nombre del website que vamos a desarrollar en esta serie de tutoriales. Tal como esperas, el objetivo del website es proveer un catalogo online para una pequeña libreria, donde los usuarios exploren los libros disponibles y administren sus cuentas.

+ +

Este ejemplo ha sido cuidadosamente elegido porque puede escalarse para mostrar tantos o pocos detalles como necesitemos, de igual forma puede usarse para presentar casi todas las caracteristicas de Express. Mas importante aún, nos permite proporcionar una ruta guiada a traves de la funcionalidad que necesita cualquier sitio web:

+ + + +

Aunque este ejemplo se puede extender mucho mas, se llama LocalLibrary por una razón , esperamos mostrar informacion minima que le ayudara a comenzar a utilizar Express rapidamente. Como resultado, almacenaremos informacion acerca de libros, copias de libros, autores y otra informacion clave. Sin embargo, no almacenaremos informacion sobre otros elementos que una biblioteca pueda tener, o proveer la infraestructura necesaria para soportar multiples sitios u otras caracteristicas de grandes bibliotecas.  

+ +

Estoy atascado, donde puedo obtener el codigo fuente?

+ +

A medida que avance, le proporcionaremos los fragmentos de codigo adecuado para que usted los copie y pegue en cada punto, ademas, habrá otro código con el proposito de que usted lo complete para afianzar su conocimiento (con alguna orientacion).

+ +

Si aun asi sigues atasaco, puedes encontrar la version completamente desarrollada del sitio web en Github aqui.

+ +
+

Note: Las versiones especificas de node, Express, y los otros modulos con los que se probó esta documentación estan enumeradas en el projecto package.json.

+
+ +

Summary

+ +

Ahora que sabes un poco mas del sitio web LocalLIbrary y lo que vas a aprender, es tiempo de comenzar a crear un skeleton projecto para contener nuestro ejemplo.

+ +

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs/skeleton_website", "Learn/Server-side/Express_Nodejs")}}

+ +

In this module

+ + diff --git a/files/es/learn/server-side/index.html b/files/es/learn/server-side/index.html new file mode 100644 index 0000000000..e22f39084f --- /dev/null +++ b/files/es/learn/server-side/index.html @@ -0,0 +1,57 @@ +--- +title: Programación lado servidor +slug: Learn/Server-side +tags: + - Aprendizaje + - Aterrizaje + - Codificación de scripts + - Principiante + - Programación lado servidor + - Servidor + - Tema + - introducción +translation_of: Learn/Server-side +--- +
{{LearnSidebar}}
+ +

El tema Páginas Dinámicas  Programación lado servidor contiene una serie de módulos en los que se enseña como crear sitios web dinámicos, sitios que entregan información personalizada como respuesta a las peticiones HTTP. El modulo ofrece una introducción generica a la programación de lado servidor además de guías para principiantes sobre como usar frameworks como Django (Python) y Express(Node.js/JavaScript) para crear aplicaciones web basicas.

+ +

La mayoría de los principales sitios web utilizan alguna forma de tecnología de lado servidor para presentar dinámicamente datos cuando sean requeridos. Por ejemplo, imagina cuántos productos están disponibles en Amazon e imagina cuántas entradas han sido escritas en Facebook. Presentar todo esto usando páginas estáticas completamente diferentes sería completamente ineficiente, por lo que estos sitios en lugar de ello presentan plantillas estáticas (construidas usando HTML, CSS, y JavaScript), y actualizan dinámicamente los datos presentados dentro de esas plantillas cuando se necesiten, ej. cuando quieres ver un producto diferente en Amazon.

+ +

En el mundo moderno del desarrollo web, el aprendizaje del desarrollo de lado servidor es altamente recomendado.

+ +

Itinerario de aprendizaje

+ +

Empezar con la programación lado servidor es normalmente más fácil que con el desarrollo del lado cliente, ya que los sitios web dinámicos tienden a efectuar un montón de operaciones muy similares (recuperar datos de una base y presentarlos en una página, validar datos introducidos por los usuarios y guardarlos en la base, comprobar los permisos e inicios de sesión de los usuarios, etc.), y se construyen usando web frameworks que hacen muy facilmente éstas y otras operaciones comunes en un servidor web.

+ +

Un conocimiento básico de conceptos de programación (o de un lenguaje de programación en particular) es útil, pero no imprescindible. Igualmente, no hace falta ser un experto en codificación lado cliente, pero un conocimiento básico te ayudará a trabajar mejor con los desarrolladores creando tu "front-end" de web lado cliente.

+ +

Necesitarás entender "cómo tabaja la web". Te recomendamos que leas primero los siguientes temas:

+ + + +

Con ese conocimiento básico estarás preparado para recorrer el camino a través de los módulos de esta sección.

+ +

Módulos

+ +

Este tema contiene los siguientes módulos. Deberías comenzar por el primer módulo y a continuación  ir a uno de los módulos siguientes, que muestran cómo trabajar con dos lenguajes muy populares de lado servidor usando los web frameworks adecuados.

+ +
+
Primeros pasos en la programación lado servidor de sitios web
+
Este módulo proporciona información acerca de la programación lado servidor de sitios web sin adentrarse en la tecnología de los servidores, incluyendo respuestas a las preguntas a cuestiones fundamentales acerca de la programación de lado servidor — "¿qué es?", "¿en qué se diferencia de la programación de lado cliente?" y "¿porqué es tan útil?" — y una visión general de algunos de los web frameworks de lado servidor más populares e indicaciones de cómo seleccionar el más adecuado para tu sitio. Finalmente proporcionaremos una sección de introducción a la seguridad en servidores web.
+
Django Web Framework (Python)
+
Django es un web framework extremadamete popular y con funcionalidad completa, escrito en Python. El módulo explica porqué Django es tan buen framework de servidor web, cómo configurar un entorno de desarrollo y cómo realizar tareas comunes con él.
+
Express Web Framework (Node.js/JavaScript)
+
Express es un web framework popular, escrito en JavaScript y hospedado dentro del entorno de ejecución en tiempo real "node.js". El módulo explica algunos de los beneficios clave de este framework, cómo configurar tu entorno de desarrollo y cómo realizar tareas comunes de desarrollo y despliegue web.
+
+ +

Ver también

+ +
+
Node servidor sin framework
+
Este artículo proporciona un servidor de ficheros estático, construido con Node.js puro, para aquellos de vosotros que no os apetezca usar un framework.
+
diff --git a/files/es/learn/server-side/node_server_without_framework/index.html b/files/es/learn/server-side/node_server_without_framework/index.html new file mode 100644 index 0000000000..11826d3e73 --- /dev/null +++ b/files/es/learn/server-side/node_server_without_framework/index.html @@ -0,0 +1,81 @@ +--- +title: Servidor Node sin framework +slug: Learn/Server-side/Node_server_without_framework +translation_of: Learn/Server-side/Node_server_without_framework +--- +
{{LearnSidebar}}
+ +

Este artículo proporciona un servidor de ficheros estático simple construido con Node.js puro, para aquellos de vosotros que no quieran usar un framework.

+ +

NodeJS has many frameworks to help you get your server up and running, the most popular being:

+ + + +

There is however not a solution that will suit every situation. A developer may need to build his/her own server, without any other dependency.

+ +

Example

+ +

Below is a simple static file server built with NodeJS:

+ +
var http = require('http');
+var fs = require('fs');
+var path = require('path');
+
+http.createServer(function (request, response) {
+    console.log('request ', request.url);
+
+    var filePath = '.' + request.url;
+    if (filePath == './') {
+        filePath = './index.html';
+    }
+
+    var extname = String(path.extname(filePath)).toLowerCase();
+    var contentType = 'text/html';
+    var mimeTypes = {
+        '.html': 'text/html',
+        '.js': 'text/javascript',
+        '.css': 'text/css',
+        '.json': 'application/json',
+        '.png': 'image/png',
+        '.jpg': 'image/jpg',
+        '.gif': 'image/gif',
+        '.wav': 'audio/wav',
+        '.mp4': 'video/mp4',
+        '.woff': 'application/font-woff',
+        '.ttf': 'application/font-ttf',
+        '.eot': 'application/vnd.ms-fontobject',
+        '.otf': 'application/font-otf',
+        '.svg': 'application/image/svg+xml'
+    };
+
+    contentType = mimeTypes[extname] || 'application/octet-stream';
+
+    fs.readFile(filePath, function(error, content) {
+        if (error) {
+            if(error.code == 'ENOENT'){
+                fs.readFile('./404.html', function(error, content) {
+                    response.writeHead(200, { 'Content-Type': contentType });
+                    response.end(content, 'utf-8');
+                });
+            }
+            else {
+                response.writeHead(500);
+                response.end('Sorry, check with the site admin for error: '+error.code+' ..\n');
+                response.end();
+            }
+        }
+        else {
+            response.writeHead(200, { 'Content-Type': contentType });
+            response.end(content, 'utf-8');
+        }
+    });
+
+}).listen(8125);
+console.log('Server running at http://127.0.0.1:8125/');
+ +

To do

+ +

It would be nice to extend this article to explain how the above code works, and perhaps also show an extended version that serves static files and also handles some kind of dynamic requests too.

diff --git a/files/es/learn/server-side/primeros_pasos/index.html b/files/es/learn/server-side/primeros_pasos/index.html new file mode 100644 index 0000000000..19a5454b4b --- /dev/null +++ b/files/es/learn/server-side/primeros_pasos/index.html @@ -0,0 +1,47 @@ +--- +title: Primeros Pasos en la Programación de Lado-Servidor +slug: Learn/Server-side/Primeros_pasos +tags: + - Aprendizaje + - Aterrizaje + - Codificación de scripts + - Guía + - Principiante + - Programación lado servidor + - introducción +translation_of: Learn/Server-side/First_steps +--- +
{{LearnSidebar}}
+ +

En este, nuestro módulo sobre programación de Lado-Servidor, contestaremos a unas pocas preguntas fundamentales - "¿Qué es?", "¿En qué se diferencia de la programación de Lado-Cliente?" y "¿Porqué es tan útil?". Proporcionaremos un vistazo de algunos de los "web-frameworks" de lado-servidor más populares, junto con indicaciones de cómo seleccionar el framework más adecuado para crear tu primer sitio. Finalmente proporcionaremos un artículo introductorio de alto nivel sobre seguridad en el servidor web. 

+ +

Prerequisitos

+ +

Antes de comenzar este módulo no necesitas tener ningún conocimiento de programación de sitios web de lado-servidor, y tampoco de ningún otro tipo de programación.

+ +

Necesitarás entender "cómo funciona la web". Te recomendamos que leas primero los siguientes temas:

+ + + +

Con este conocimiento básico estarás listo para recorrer el camino a través de los módulos de esta sección.

+ +

Guías

+ +
+
Introducción al lado servidor
+
¡Bienvenidos al curso MDN de programación para principiantes de lado servidor! En este primer artículo enfocamos la programación de Lado-Servidor desde un nivel alto, respondiendo a preguntas tales como "¿qué es?", "¿en qué se diferencia de la programación de Lado-Cliente?" y "¿porqué es tan útil?". Después de leer este artículo entenderás el poder adicional para los sitios web disponible a través de la codificación lado-servidor.
+
Visión general Cliente-Servidor
+
Ahora que conoces el propósito y beneficios potenciales de la programación lado-servidor examinaremos en detalle qué pasa cuando un servidor recibe una "petición dinámica" desde un explorador web. Como el código de lado-servidor de la mayoría de sitios web gestiona las peticiones y las respuestas de forma similar, ésto te ayudará entender qué necesitas hacer cuando escribes tu propio código.
+
Web frameworks de lado-servidor
+
El anterior artículo te mostró lo que necesita una aplicación web de lado servidor para responder a las peticiones de un explorador web. Ahora te mostraremos cómo los web frameworks pueden simplificar estas tareas y ayudarte a seleccionar el framework correcto para tu primera aplicación web de lado servidor.
+
Seguridad de Sitios Web
+
La seguridad de los sitios web requiere vigilancia en todos los aspectos del diseño y uso del sitio . Este artículo introductorio no te convertirá en un gurú de la seguridad de sitios web, pero te ayudará a entender los primeros pasos importantes que deber dar para robustecer tu aplicación web contra las amenazas más comunes.
+
+ +

Evaluaciones

+ +

Este módulo "visión general" no hace ninguna evaluación ya que no te hemos enseñado ningún código todavía. Esperamos que en este punto tengas una comprensión de qué clase de funcionalidad puedes distribuir usando programación de lado servidor y habrás tomado una decisión sobre el web framework de lado servidor que usarás para crear tu primer sitio. 

diff --git "a/files/es/learn/server-side/primeros_pasos/introducci\303\263n/index.html" "b/files/es/learn/server-side/primeros_pasos/introducci\303\263n/index.html" new file mode 100644 index 0000000000..0b0d2da59e --- /dev/null +++ "b/files/es/learn/server-side/primeros_pasos/introducci\303\263n/index.html" @@ -0,0 +1,192 @@ +--- +title: Introducción al lado servidor +slug: Learn/Server-side/Primeros_pasos/Introducción +tags: + - Aprendizaje + - Codificación de scripts + - Guía + - Principiante + - Programación lado servidor + - Servidor + - introducción +translation_of: Learn/Server-side/First_steps/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}
+ +

¡Bienvenidos al curso MDN de programación para principiantes de lado servidor! En este primer artículo enfocamos la programación de Lado-Servidor desde un nivel alto, respondiendo a preguntas tales como "¿qué es?", "¿en qué se diferencia de la programación de Lado-Cliente?" y "¿porqué es tan útil?". Después de leer este artículo entenderás el poder adicional para los sitios web disponible a través de la codificación lado-servidor.

+ + + + + + + + + + + + +
Prerequisitos:Nociones básicas de computación. Entender lo que es un servidor web.
Objetivo:Familiarizarse con lo que es la programación de lado servidor, qué puede hacer y en qué se diferencia de la programación de lado cliente.
+ +

La mayoría de los grandes sitios web usan código de lado servidor para presentar, cuando se necesitan, diferentes datos, generalmente extraidos de una base de datos almacenada en un servidor y enviada al cliente para ser presentada mediante algún código (ej, HTML y JavaScript). Quizá el beneficio más significativo de la codificación de lado servidor es que te permite confeccionar el contenido del sitio web para usuarios individuales. Los sitios dinámicos pueden resaltar contenido que es más relevante basándose en las preferencias del usuario y sus hábitos. Puede hacer también que los sitios sean más fáciles de usar al almacenar las preferencias personales y la información - por ejemplo reusando los detalles de la tarjeta de crédito guardados para agilizar los pagos siguientes. Puede incluso permitir la interacción con los usuarios fuera del sitio, enviando notificaciones y actualizaciones via email o a traves de otros canales. Todas estas capacidades permite un mayor compromiso con los usuarios. 

+ +

En el mundo moderno del desarrollo web, el aprendizaje sobre desarrollo de lado servidor es altamente recomendable.

+ +

¿Qué es la programación de sitios web de lado servidor?

+ +

Los exploradores web se comunican con los servidores web usando el Protocolo de Transporte de Hyper Texto (HyperText Transport Protocol ({{glossary("HTTP")}}). Cuando pinchas en un enlace en una página web, envías un formulario o ejecutas una búsqueda, se envía una peticion HTTP desde tu explorador web al servidor web de destino. La petición incluye un URL que identifica el recurso afectado, un método que define la acción requerida (por ejemplo, obtener, borrar o publicar el recurso), y puede incluir información adicional codificada en parámetros en el URL (los pares campo-valor enviados en una cadena de consulta (query string), como datos POST (datos enviados mediate el método POST de HTTP,  HTTP POST method), o en {{glossary("Cookie", "associated cookies")}}.

+ +

Los servidores web esperan los mensajes de petición de los clientes, los procesan cuando llegan y responden al explorador web con un mensaje de respuesta HTTP. La repuesta contiene una línea de estado indicando si la petición ha tenido éxito o no (ej, "HTTP/1.1 200 OK" en caso de éxito). El cuerpo de una respuesta exitosa a una petición podría contener el resurso solicitado (ej, una nueva página HTML, o una imagen, etc...), que el explorador web podría presetar en pantalla.

+ +

Sitios Estáticos

+ +

El diagrama de abajo muestra una arquitectura de servidor web básica correspondiente a un sitio estático (un sitio estático es aquél que devuelve desde el servidor el mismo contenido insertado en el código "hard coded" siempre que se solicita un recurso en particular). Cuando un usuario quiere navegar a una página, el explorador envía una petición HTTP "GET" especificando su URL. El servidor recupera de su sistema de ficheros el documento solicitado y devuelve una respuesta HTTP que contiene el documento y un estado de éxito "success status" (normalmente 200 OK). Si el fichero no puede ser recuperado por alguna razón, se devuelve un estado de error (ver respuestas de error del cliente and respuestas de error del servidor).

+ +

A simplified diagram of a static web server.

+ +

Sitios Dinámicos

+ +

Un sitio dinámico es aquél en que algun contenido de la respuesta está generado dinámicamente sólo cuando se necesita. En un sitio web dinámico las páginas HTML se crean normalmente insertando datos desde una base en variables dentro de plantillas HTML (esta es una forma mucho más eficiente de almacenar gran cantidad de contenido que la que usan los sitios web estáticos). Un sitio dinámico puede devolver datos diferentes para un URL basados en la información proporcionada por el usuario o sus preferencias almacenadas y puede realizar otras operaciones como parte de la devolución de respuesta (ej, enviar notificaciones).

+ +

La mayor parte del código para soportar un sitio web dinámico debe correr en el servidor. La creación de este código se conoce como "programación de lado-servidor" (o algunas veces "back-end scripting").

+ +

El diagrama de abajo muestra una arquitectura simple para unsitio web dinámico. Como en el diagrama previo, los exploradores web envían peticiones HTTP al servidor, el servidor procesa a continuación las peticiones y devuelve las respuestas HTTP apropiadas. Las peticiones de recursos estáticos son gestionadas de la misma manera que para los sitios estáticos (los recursos estáticos son cualquier fichero que no cambia - generalmente: CSS, JavaScript, Imágenes, ficheros PDF creados previamente, etc...)

+ +

A simplified diagram of a web server that uses server-side programming to get information from a database and construct HTML from templates. This is the same diagram as is in the Client-Server overview.

+ +

Las peticiones de recursos dinámicos, por el contrario, son reenviadas (2) al código del lado-servidor (mostrado en el diagrama como Web Application). Para las "peticiones dinámicas" el servidor interpreta la petición, lee de la base de datos la información requerida (3), combina los datos recuperados con las plantillas HTML (4), y envía de vuelta una respuesta que contiene el HTML generado (5,6). 

+ +
+

¿Son iguales la programación del lado-servidor y lado-cliente?

+
+ +

Prestemos ahora nuestra atención al código involucrado en la programación de lado-servidor y lado-cliente. En cada caso, el código es significativamente diferente:

+ + + +

El código que se ejecuta en el explorador se conoce como código de lado-cliente, y su principal preocupación es la mejora de la apariencia y el comportamiento de una página web entregada. Esto incluye la selección y estilo de los componentes UI, la creación de layouts, navegación, validación de formularios, etc. Por otro lado, la programación de sitios web de lado servidor en su mayor parte implica la elección de qué contenido se ha de devolver al explorador como respuesta a sus peticiones. El código de lado-servidor gestiona tareas como la validación de los datos enviados y las peticiones, usando bases de datos para almacenar y recuperar datos, y enviando los datos correctos al cliente según se requiera.

+ +

El código del lado cliente está escrito usando HTMLCSS, y JavaScript — es ejecutado dentro del explorador web y tiene poco o ningún acceso al sistema operativo subyacente (incluyendo un acceso limitado al sistema de ficheros).

+ +

Los desarrolladores web no pueden controlar qué explorador web usará cada usuario para visualizar un sitio web — los exploradores web proporcionan niveles de compatibilidad inconsistentes con las características de codificación lado cliente, y parte del reto de la programación de lado cliente es gestionar con dignidad las diferencias de soporte entre exploradores.

+ +
El código del lado servidor puede escribirse en cualquier número de lenguajes de programación — ejemplos de lenguajes de programación populares incluyen PHP, Python, Ruby, C# y NodeJS(JavaScript). El código del lado servidor tiene acceso completo al sistema operativo del servidor y el desarrollador puede elegir qué lenguaje de programación (y qué versión específica) desea usar.
+ +
Los desarrolladores generalmente escriben su código usando web frameworks. Los web framworks son colecciones de funciones, objetos, reglas y otras construcciones de código diseñadas para resolver problemas comunes, acelerar el desarrollo y simplificar los diferentes tipos de tareas que se han de abordar en un dominio en particular.
+ +
De nuevo, mientras que, tanto el código lado cliente y el lado servidor usan frameworks, los dominios son muy diferentes, y por lo tanto también lo son los frameworks. Los frameworks del lado cliente simplifican los diseños y las tareas de presentación mientras que los del lado servidor proporcionan un montón de funcionalidades "comunes" que tendría que haber implementado uno mismo (ej, soporte para las sesiones, soporte para los usuarios y autenticación, acceso fácil a la base de datos, librerías de plantillas, etc...).
+ +
+

Nota: Los frameworks del lado cliente se usan con frecuencia para acelerar el desarrollo del código del lado cliente, pero también se puede elegir escribir todo el código a mano; de hecho, escribir el código a mano puede ser más rápido y más eficiente si sólo se necesita una UI para sitio web pequeña y simple. Por contra, casi nunca se consideraría escribir el componente del lado servidor de una aplicación web ("web app") sin un framework — implementar una característica vital como un servidor HTTP es realmente difícil de hacer de la nada en un lenguaje como, por ejemplo, Python, pero los  web frameworks de Python como Django proporcionan uno  listo para usar, junto con otras herramientas muy útiles.

+
+ +

¿Qué se puede hacer en el lado-servidor?

+ +

La programación del lado-servidor es muy útil porque nos permite distribuir eficientemente información a medida para usuarios individuales y por lo tanto crear una experiencia de usuario mucho mejor.

+ +

Compañías como Amazon utilizan la programación del lado-servidor para construir resultados de búsquedas de productos, hacer sugerencias sobre productos escogidos basados en las preferencias del cliente y sus hábitos de compra previos, simplificar las adquisiciones, etc. Los bancos usan la programación del lado-servidor para almacenar la información sobre las cuentas y permitir ver y realizar transacciones sólo a los usuarios autorizados. Otros servicios como Facebook, Twitter, Instagram y Wikipedia usan la programación de lado-servidor para destacar, compartir y controlar el acceso al contenido interesante.

+ +

Algunos de los usos y beneficios comunes de la programación de lado-servidor se lista debajo. Notarás que hay algo de solapamiento.

+ +

Almacenaje y distribución eficiente de información

+ +

Imagina cuántos productos están disponibles en Amazon, e imagina cuántas entradas se han escrito en Facebook. Crear una página estática separada para cada producto o entrada sería completamente ineficiente.

+ +

La programación de lado-servidor nos permite por el contrario almacenar la información en una base de datos y construir dinámicamente y devolver ficheros HTML y de otros tipos (ej, PDFs, imágenes, etc.). También es posible devolver simplemente datos ({{glossary("JSON")}}, {{glossary("XML")}}, etc.) para presentar mediante los web frameworks adecuados del lado-cliente (esto reduce la carga de procesamiento del servidor y la cantidad de datos que se necesitan enviar).

+ +

El servidor no se limita a enviar información de las bases de datos, y podría además devolver el resultado de herramientas de software o datos de servicios de comunicación. El contenido puede incluso ser dirigido por el tipo de dispositivo cliente que lo está recibiendo.

+ +

Debido a que la información está en una base de datos, puede también ser compartida y actualizada con otros sistemas de negocio (por ejemplo, cuando se venden los productos online o en una tienda, la tienda debería actualizar su base de datos de inventario.

+ +
+

Nota: Tu imaginación no tiene que trabajar duro para ver el beneficio de la codificación de lado-servidor para el almacenaje y distribución de información:

+ +
    +
  1. Vete a Amazon o a cualquier otro sitio de comercio electrónico "e-commerce".
  2. +
  3. Busca por un número de palabras clave y nota como la estructura de la página no cambia, incluso aunque cambien los resultados. 
  4. +
  5. Abre dos o tres productos diferentes. Fíjate de nuevo como tienen una estructura y diseño común, pero el contenido para los diferentes productos ha sido extraido de la base de datos.
  6. +
+ +

Para un término de búsqueda común (digamos "pez") puedes ver literalmente millones de valores retornados. Usar una base de datos permite que éstos sean almacenados y compartidos de forma eficiente, y permite que la presentación de la información esté controlada en un solo sitio.

+
+ +

Experiencia de usuario personalizada

+ +

Los servidores pueden almacenar y usar la información acerca de los clientes para proporcionar una experiencia de usuario conveniente y dirigida. Por ejemplo, muchos usuarios almacenan tarjetas de crédito de forma que los detalles no tienen que ser introducidos de nuevo. Sitios como Google Maps usan la localización de tu casa y la actual para proporcionar una información sobre la ruta a seguir y resaltar los negocios locales en los resultados de búsqueda.

+ +

Un análisis profundo de los hábitos del usuario se puede usar para anticipar sus intereses y personalizar las respuestas y notificaciones futuras, proporcionando, por ejemplo, una lista de las localizaciones visitadas o populares que querrías buscar en un mapa.

+ +
+

Nota: Vete a Google Maps como usuario anónimo, selecciona el botón Direcciones, e introduce los puntos de partida y destino de un viaje. Ahora inicia sesión en el sistema con tu cuenta de Google, si tienes una (en el panel de abajo aparece información acerca de este proceso donde seleccionas direcciones). El sitio web te permitirá ahora seleccionar las localizaciones de casa y trabajo como puntos de partida y destino (o almacenar estos detalles si no lo has hecho así).

+
+ +

Acceso controlado al contenido 

+ +

La programación de lado-servidor permite a los sitios restringir el acceso a usuarios autorizados y servir sólo la información que se le permite ver al usuario.

+ +

Ejemplos del mundo real incluyen:

+ + + +
+

Nota: Considera otros ejemplos reales donde el acceso al contenido está controlado. Por ejemplo, ¿qué puedes ver si vas al sitio online de tu banco? Inicia sesión con tu cuenta — ¿qué información adicional puedes ver y modificar? ¿Qué información puedes ver y sólo el banco puede cambiar?

+
+ +

Almacenar información de sesión/estado

+ +

La programación de lado-servidor permite a los desarrolladores hacer uso de las sesiones — es básicamente un mecanismo que permite al servidor almacenar información sobre el usuario actual del sitio u enviar diferentes respuestas basadas en esa información. Esto permite, por ejemplo, que un sitio sepa que un usuario ha iniciado sesión previamente y presente enlaces a sus correos, o a su historial de órdenes, o quizá guardar el estado de un simple juego de forma que el usuario pueda volver al sitio de nuevo y retomar el juego donde lo dejó.

+ +
+

Nota: Visita el sitio de un periódico que tenga un modelo de subscripción y abre un puñado de pestañas (ej, The Age). Continua visitando el sitio durante unos pocos días/horas. En algún momento serás finalmente redirigido a las páginas que explican cómo suscribirte y se te impedirá el acceso a los artículos. Esta información es un ejemplo de información de sesión almacenada en cookies.

+
+ +

Notificaciones y comunicación

+ +

Los servidores pueden enviar notificaciones de tipo general o específicas de usuario a través del propio sitio web o vía correo electrónico, SMS, mensajería instanténea, conversaciones de video u otros servicios de comunicación.

+ +

Unos pocos ejemplos incluyen:

+ + + +
+

Nota: El tipo de notificación más común es una "confirmación de registro". Elige uno cualquiera de los grandes sitios en que estés interesado (Google, Amazon, Instagram, etc.) y crea una cuenta nueva usando tu dirección de correo. En breve recibirás un email de confirmación de registro, o solicitando un acuse de recibo para activar la cuenta.

+
+ +

Análisis de datos

+ +

Un sitio web puede recolectar un montón de datos acerca de los usuarios: qué es lo que buscan, qué compran, qué recomiendan, cuánto tiempo permanecen en cada página. La programación de lado-servidor puede utilizarse para refinar las respuestas basándose en el análisis de estos datos.

+ +

Por ejemplo, Amazon y Google anuncian ambos productos basados en búsquedas previas (y adquisiciones).

+ +
+

Nota: Si eres usuario de Facebook vete a tu muro y hecha un ojo a la ristra de entradas. Fíjate como algunas de las entradas no están en orden numérico - en particular las entradas con más "me-gusta" están con frecuencia en lugares más altos de la lista que las entradas más recientes. Echa un ojo también a qué clase de anuncios te están mostrando — podrías ver anuncios de cosas que has mirado en otros sitios. El algoritmo de Facebook para resaltar contenido y anuncios puede ser un poco misterioso, pero está claro que lo que hace depende de lo que te gusta y de tus hábitos de visualización!

+
+ +

Sumario

+ +

Felicidades, has alcanzado el final de primer artículo sobre programación de lado-servidor. 

+ +

Ahora ya has aprendido que el código de lado-servidor se ejecuta en un servidor web y que su papel principal es controlar qué información se envía al usuario (mientras que el código de lado-cliente gestiona principalmente la estructura y presentación  de esos datos al usuario).

+ +

También deberías comprender que es útil porque nos permite crear sitios web que distribuyen de forma eficiente información seleccionada dirigida a usuarios individuales y tener una buena idea de algunas de las cosas que podrías ser capaz de hacer cuando seas un programador de lado-servidor.

+ +

Finalmente, deberías comprender que el código de lado-servidor se puede escribir en un gran número de lenguajes de programación y que deberías usar un web framework para hacer más fácil el proceso completo.

+ +

En un artículo futuro te ayudaremos a escoger el mejor web framework para tu primer sitio; Aunque a continuación te llevaremos a través de las principales interacciones cliente-servidor en un poco más de detalle.

+ +

{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}

diff --git a/files/es/learn/server-side/primeros_pasos/seguridad_sitios_web/index.html b/files/es/learn/server-side/primeros_pasos/seguridad_sitios_web/index.html new file mode 100644 index 0000000000..c2630fc050 --- /dev/null +++ b/files/es/learn/server-side/primeros_pasos/seguridad_sitios_web/index.html @@ -0,0 +1,177 @@ +--- +title: Seguridad de Sitios Web +slug: Learn/Server-side/Primeros_pasos/seguridad_sitios_web +tags: + - Aprendizaje + - Codificación de scripts + - Guía + - Principiante + - Programación de lado servidor + - Seguridad + - Seguridad Web + - Seguridad de sitios Web + - introducción +translation_of: Learn/Server-side/First_steps/Website_security +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
+ +

La Seguridad web require vigilancia en todos los aspectos del diseño y uso de un sitio web. Este artículo introductorio no te hará un gurú de la seguridad en sitios web, pero te ayudará a entender de donde vienen las amenazas y qué puedes hacer para fortalecer tu aplicación web contra los ataques más comunes.

+ + + + + + + + + + + + +
Pre-requisitos:Conocimientos de computación básicos.
Objetivo:Entender las amenazas más comunes para la seguridad de una aplicación web y lo que puedes hacer para reducir el riesgo de que tu sitio sea hackeado.
+ +

¿Qué es la seguridad de sitios web?

+ +

¡Internet es un sitio peligroso! Con mucha frecuencia escuchamos sobre sitios web que dejan de estar disponibles debido a ataques de denegación de servicio, o presentan información modificada (y con frecuencia dañada) en sus páginas de inicio. En otros casos de alto nivel, millones de contraseñas, direcciones de correo electrónico y detalles de tarjetas de crédito han sido filtrados al dominio público, exponiendo a los usuarios del sitio web tanto a bochorno personal como a riesgo finaciero.

+ +

El propósito de la seguridad web es prevenir ataques de esta (o de cualquier otra) clase. Mas formalmente, la seguridad es la acción/práctica de proteger sitios web del acceso, uso, modificación, destrucción o interrupción, no autorizados.

+ +

La seguridad de sitios web eficaz requiere de esfuerzos de diseño a lo largo de la totalidad del sitio web: en tu aplicación web, en la configuración del servidor web, en tus políticas para crear y renovar contraseñas, y en el código del lado cliente. Al mismo tiempo que todo esto suena muy inquietante, la buena noticia es que si estás usando un framework web de lado servidor, es casi seguro que habilitará por defecto mecanismos de defensa robustos y bien pensados contra gran cantidad de los ataques más comunes. Otros ataques pueden mitigarse por medio de la configuración de tu servidor web, por ejemplo habilitando HTTPS. Finalmente, hay herramientas de escaneado de vulnerabilidades disponibles públicamente que pueden ayudarte a averiguar si has cometido algún error obvio.

+ +

El resto de este artículo proporciona más detalle sobre unas pocas amenazas comunes y algunos de los pasos simples que puedes dar para proterger tu sitio.

+ +
+

Nota: Este es un tema de introducción, diseñado para ayudarte a pensar sobre la seguridad de sitios web. No pretende ser exhaustivo.

+
+ +

Amenazas contra la seguridad de sitios web

+ +

Esta sección lista sólo algunas pocas de las amenazas más comunes para los sitios web y cómo son mitigadas. A medida que vayas leyendo, fíjate cómo las amenazas tienen éxito cuando la aplicación web, ¡o confía o no es lo suficientemente paranoica acerca de los datos que vienen del explorador web!

+ +

Cross-Site Scripting (XSS)

+ +

XSS es un término que se usa para describir una clase de ataques que permiten al atacante inyectar scripts de lado cliente, a través del sitio web, hasta los exploradores de otros usuarios. Como el código inyectado va del servidor del sitio al explorador, se supone de confianza, y de aquí que pueda hacer cosas como enviar al atacante la cookie de autorización al sitio del usuario. Una vez que el atacante tiene la cookie pueden iniciar sesión en el sitio como si fuera el verdadero usuario y hacer cualquier cosa que pueda hacer éste. Dependiendo de que sitio sea, esto podría incluir acceso a los detalles de su tarjeta de crédito, ver detalles de contactos o cambiar contraseñas, etc.

+ +
+

Nota: Las vulnerabilidades XSS han sido históricamente más comunes que las de cualquier otro tipo.

+
+ +

Hay dos aproximaciones principales para conseguir que el sitio devuelva scripts inyectados al explorador — se conocen como vulnerabilidades XSS reflejadas y persistentes.

+ + + +

La mejor defensa contra las vulnerabilidades XSS es eliminar o deshabilitar cualquier etiqueta que pueda contener instrucciones para ejecutar código. En el caso del HTML ésto incluye etiquetas como <script>, <object>, <embed>, y <link>.

+ +
+

El proceso de modificar los datos del usuario de manera que no puedan utilizarse para ejecutar scripts o que afecten de otra forma la ejecución del código del servidor, se conoce como "desinfección de entrada" (input sanitization). Muchos frameworks web desinfectan automáticamente la entrada del usuario desde formularios HTML, por defecto.

+
+ +

Inyección SQL

+ +

Las vulnerabilidades de Inyección SQL habilitan que usuarios maliciosos ejecuten código SQL arbitrario en una base de datos, permitiendo que se pueda acceder a los datos, se puedan modificar o borrar, independientemente de los permisos del usuario. Un ataque de inyección con éxito, podría falsificar identidades, crear nuevas identidades con derechos de administración, acceder a todos los datos en el servidor o destruir/modificar los datos para hacerlos inutilizables.

+ +

Esta vulnerabilidad está presente si la entrada del usuario que se pasa a la sentencia SQL subyacente puede cambiar el significado de la misma. Por ejemplo, considera el código de abajo, que pretende listar todos los usuarios con un nombre en particular (userName) que ha sido suministrado en un formulario HTML:

+ +
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
+ +

Si el usuario introduce su nombre real, la cosa funciona como se pretende. Sin embargo un usuario malicioso podría cambiar completamente el comportamiento de esta sentencia SQL a la nueva sentencia de abajo, simplemente especificando para userName el texto de abajo en "negrilla". La sentencia modificada crea una sentencia SQL válida que borra la tabla  users y selecciona todos los datos de la tabla userinfo  (revelando la información de todos los usuarios). Esto funciona por que la primera parte del texto inyectado (a';) completa la sentencia original (' es el símbolo para indicar una cadena literal en SQL).

+ +
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
+
+ +

La manera de evitar esta clase de ataque es asegurar que cualquier dato de usuario que se pasa a un query SQL no puede cambiar la naturaleza del mismo. Una forma de hacer ésto es eludir ('escape') todos los caracteres en la entrada de usuario que tengan un significado especial en SQL.

+ +
+

Nota: La sentencia SQL trata el caracer ' como el principio y el final de una cadena de texto. Colocando el caracter barra invertida \ delante, "eludimos" el símbolo (\'), y le decimos a SQL que lo trate como un caracter de texto (como parte de la misma cadena).

+
+ +

En la sentencia de abajo eludimos el carácter '. SQL interpretará ahora como "nombre" la cadena de texto completa mostrada en negrilla (!un nombre muy raro desde luego, pero no dañino¡)

+ +
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
+
+
+ +

Los frameworks web con frecuencia tienen cuidado de hacer por tí la elusión de caracteres. Django, por ejemplo se asegura que cualquier dato de usuario que se pasa a los conjuntos de queries (modelo de queries) está corregido.

+ +
+

Nota: Esta sección se sustenta aquí en la información de Wikipedia.

+
+ +

Cross Site Request Forgery (CSRF)

+ +

Los ataques de CSRF permiten que un usuario malicioso ejecute acciones usando las credenciales de otro usuario sin el conocimiento o consentimiento de éste.

+ +

Este tipo de ataque se explica mejor con un ejemplo. John es un usuario malicioso que sabe que un sitio en particular permite a los usuarios que han iniciado sesión enviar dinero a una cuenta específica usando una petición HTTP POST que incluye el nombre de la cuenta y una cantidad de dinero. John construye un formulario que incluye los detalles de su banco y una cantidad de dinero como campos ocultos, y lo envía por correo electrónico a otros usuarios del sitio (con el botón de Enviar camuflado como enlace a un sitio "hazte rico rápidamente").

+ +

Si el usuario pincha el botón de enviar, se envía al servidor una petición HTTP POST que contiene los detalles de la transacción y todos los cookies de lado-cliente que el explorador asocia con el sitio (añadir cookies asociados con el sitio es un comportamiento normal de los exploradores). El servidor comprobará los cookies, y los usará para determinar si el usuario ha iniciado sesión o no y si tiene permiso para hacer la transacción.

+ +

El resultado es que cualquier usuario que pinche en el botón Enviar mientras tiene la sesión iniciada en el sitio comercial hará la transacción. ¡John se hará rico!

+ +
+

Nota: El truco aquí es que John no necesita tener acceso a los cookies del usuario (o acceso a sus credenciales) — El explorador del usuario almacena esta información, y la incluye automáticamente en todas las peticiones al servidor asociado.

+
+ +

Una manera de prevenir este tipo de ataque por parte del servidor es requerir que la petción POST incluya una palabra secreta específica del usuario generada por el sitio (la palabra secreta podría proporcionarla el servidor cuando envía el formulario web que se usa para hacer transferencias). Esta aproximación evita que John pueda crear su propio formulario, porque necesitaría conocer la palabra secreta que el servidor ha proporcionado para el usuario. Incluso si conociera esta palabra y creara un formulario para un usuario en particular, no podría usar el mismo formulario para atacar a todos los usuarios.

+ +

Los frameworks web incluyen con frecuencia tales mecanismos de prevención de CSRF.

+ +

Otras amenazas

+ +

Otros ataques/vulnerabilidades incluyen:

+ + + +

Hay muchas más. Para un lisado completo ver Category:Web security exploits (Wikipedia) y Category:Attack (Open Web Application Security Project).

+ +

Unos cuantos mensajes clave

+ +

Casi todos los exploits de las secciones anteriores tienen éxito cuando la aplicación web confía en los datos que vienen del explorador. Sea lo que sea que hagas para mejorar la seguridad de tu sitio web, deberías desinfectar todos los datos originados por el usuario antes de ser mostrados en el explorador, usados en queries SQL o pasados en una llamada al sistema operativo o fichero de sistema.

+ +
+

Importante: La lección más importante que debes aprender acerca de la seguridad de sitios web es nunca confíes en los datos del explorador web. Esto incluye los datos en parámetros URL de las peticionesGET, datos POST, cabeceras HTTP y cookies, ficheros subidos por los usuarios, etc. Comprueba siempre y desinfecta todos los datos entrantes. Siempre asume lo peor.

+
+ +

Otras cuantas medidas concretas que puedes tomar son:

+ + + +

Los frameworks web pueden ayudar a mitigar muchas de las vulnerabilidades más comunes.

+ +

Sumario

+ +

Este artículo ha explicado el concepto de seguridad en sitios web y algunas de las amanazas más comunes contra las que tu sitio debería empezar a protegerse. Lo más importante que deberías entender es que ¡una aplicación web no puede confiar en ningún dato que provenga de explorador web! Todos los datos de usuario deberían ser desinfectados antes de ser mostrados, o usados en queries SQL o llamadas a ficheros de sistema.

+ +

Hemos llegado al final de este módulo, tratando tus primeros pasos en la programación de lado servidor de un sitio web. Esperamos que hayas disfrutado del aprendizaje de los conceptos fundamentales y estés listo para seleccionar un framework web y empezar a programar.

+ +

{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

+ + + +

En este módulo

+ + diff --git a/files/es/learn/server-side/primeros_pasos/vision_general_cliente_servidor/index.html b/files/es/learn/server-side/primeros_pasos/vision_general_cliente_servidor/index.html new file mode 100644 index 0000000000..05ce1f9451 --- /dev/null +++ b/files/es/learn/server-side/primeros_pasos/vision_general_cliente_servidor/index.html @@ -0,0 +1,334 @@ +--- +title: Visión General Cliente-Servidor +slug: Learn/Server-side/Primeros_pasos/Vision_General_Cliente_Servidor +tags: + - Aprendizaje + - Codificación de scripts + - Guía + - Principiante + - Programación lado servidor + - Servidor + - introducción +translation_of: Learn/Server-side/First_steps/Client-Server_overview +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}
+ +

Ahora que conoces el propósito y los beneficios potenciales de la programación de lado-servidor vamos a examinar en detalle lo que ocurre cuando un servidor recibe una "petición dinámica" desde un explorador web. Ya que el código de lado servidor de la mayoría de los sitios web gestiona peticiones y respuestas de formas similares, este artículo te ayudará a entender lo que necesitas hacer para escribir la mayor parte de tu propio código.

+ + + + + + + + + + + + +
Prerequisitos:Conocimientos básicos de computación. Noción básica de lo que es un servidor.
Objetivo:Comprender lo que son las interacciones cliente-servidor en un sitio web dinámico, y en particular que operaciones necesita realizar el código de lado servidor.
+ +

No hay código real en el debate porque ¡todavía no hemos seleccionado el framework web que usaremos para escribir nuestro código! Sin embargo este debate sí que es muy relevante incluso ahora, porque el comportamiento descrito debería ser implementado por tu código de lado servidor independientemente de qué lenguaje de programación o framework web hayas seleccionado.

+ +

Servidores Web y HTTP (iniciación)

+ +

Los exploradores web se comunican con los servidores web usando el Protocolo de Transferencia de HyperTexto (HyperTextTransfer Protocol HTTP). Cuando pinchas en un enlace sobre una página web, envías un formulario o ejecutas una búsqueda, el explorador envía una petición (Request) HTTP al servidor.

+ +

Esta petición incluye:

+ + + +

Los servidores web esperan los mensajes de petición de los clientes, los procesan cuando llegan y responden al explorador web con un mensaje de respuesta HTTP. La respuesta contiene un código de estado de respuesta HTTP que indica si la petición ha tenido éxito o no (ej. "200 OK" para indicar éxito, "404 Not Found" si el resurso no ha podido ser encontrado,  "403 Forbidden" si el usuario no está autorizado a acceder al recurso, etc). El cuerpo de la respuesta de éxito a una petición GET contendría el recurso solicitado.

+ +

Cuando se devuelve una página HTML es renderizada por el explorador web. Como parte del procesamiento el explorador puede descubrir enlaces a otros recursos (ej. una página HTML normalmente referencia las páginas JavaScript y CSS), y enviará peticiones HTTP separadas para descargar estos ficheros.

+ +

Los sitios web tanto estáticos como dinámicos (abordados en las secciones siguientes) usan exactamente los mismos protocolos/patrones de comunicación.

+ +

Ejemplo de petición/respuesta GET

+ +

Puedes realizar una petición GET simplemente pinchando sobre un enlace o buscando en un sitio (como la página inicial de un motor de búsquedas). Por ejemplo, la petición HTTP que se envía cuando realizas una búsqueda en MDN del término "visión general cliente servidor" se parecerá mucho al texto que se muestra más abajo (no será idéntica porque algunas partes del mensaje dependen de tu explorador/configuración).

+ +
+

El formato de los mensajes HTTP está definido en el "estándard web" (RFC7230). No necesitas conocer este nivel de detalle, pero al menos ¡ahora sabes de donde viene todo esto!

+
+ +

La petición

+ +

Cada linea de la petición contiene información sobre ella. La primera parte se llama cabecera o header, y contiene información útil sobre la petición, de la misma manera que un HTML head contiene información útil sobre un documento (pero no el contenido mismo, que está en el cuerpo):

+ +
GET https://developer.mozilla.org/en-US/search?q=client+server+overview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/
+Accept-Encoding: gzip, deflate, sdch, br
+Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _gat=1; _ga=GA1.2.1688886003.1471911953; ffo=true
+
+ +

La primera y segunda líneas contienen la mayoría de la información de la que hemos hablado arriba:

+ + + +

La última linea contiene información sobre los cookies del lado cliente — puedes ver que en este caso el cookie incluye un id para gestionar las sesiones (Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; ...).

+ +

Las líneas restantes contienen información sobre el explorador web usado y la clase de respuestas que puede manejar. Por ejemplo, puedes ver aquí que:

+ + + +

Las peticiones HTTP también pueden tener un cuerpo, pero está vacío en este caso.

+ +

La respuesta

+ +

La primera parte de la respuesta a esta petición se muestra abajo. La cabecera o header contiene información como la siguiente:

+ + + +

Al final del mensaje vemos el contenido del cuerpo (body) — que contiene el HTML real devuelto por la respuesta.

+ +
HTTP/1.1 200 OK
+Server: Apache
+X-Backend-Server: developer1.webapp.scl3.mozilla.com
+Vary: Accept,Cookie, Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:11:31 GMT
+Keep-Alive: timeout=5, max=999
+Connection: Keep-Alive
+X-Frame-Options: DENY
+Allow: GET
+X-Cache-Info: caching
+Content-Length: 41823
+
+
+
+<!DOCTYPE html>
+<html lang="en-US" dir="ltr" class="redesign no-js"  data-ffo-opensanslight=false data-ffo-opensans=false >
+<head prefix="og: http://ogp.me/ns#">
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=Edge">
+  <script>(function(d) { d.className = d.className.replace(/\bno-js/, ''); })(document.documentElement);</script>
+  ...
+
+ +

El resto de la cabecera de la respuesta incluye información sobre la respuesta (ej. cuándo se generó), el servidor, y cómo espera el explorador manejar la página (ej. la linea X-Frame-Options: DENY le dice que al explorador que no está permitido incrustar esta página en un {{htmlelement("iframe")}} en otro sitio).

+ +

Ejemplo de petición/respuesta POST

+ +

Un HTTP POST se realiza cuando se envía un formulario que contiene información para ser guardada en el servidor.

+ +

La petición

+ +

El texto de abajo muestra la petición HTTP realizada cuando un usuario envía al sitio los detalles de un nuevo perfil. El formato de la petición es casi el mismo que en la petición GET del ejemplo mostrado previamente, aunque la primera linea identifica esta petición como POST

+ +
POST https://developer.mozilla.org/en-US/profiles/hamishwillee/edit HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Content-Length: 432
+Pragma: no-cache
+Cache-Control: no-cache
+Origin: https://developer.mozilla.org
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Content-Type: application/x-www-form-urlencoded
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/profiles/hamishwillee/edit
+Accept-Encoding: gzip, deflate, br
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; _gat=1; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _ga=GA1.2.1688886003.1471911953; ffo=true
+
+csrfmiddlewaretoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT&user-username=hamishwillee&user-fullname=Hamish+Willee&user-title=&user-organization=&user-location=Australia&user-locale=en-US&user-timezone=Australia%2FMelbourne&user-irc_nickname=&user-interests=&user-expertise=&user-twitter_url=&user-stackoverflow_url=&user-linkedin_url=&user-mozillians_url=&user-facebook_url=
+ +

La principal diferencia es que la URL no tiene parámetros. Como puedes ver, la información del formulario se codifica en el cuerpo de la petición (por ejemplo, el nombre completo del nuevo usuario se establece usando: &user-fullname=Hamish+Willee).

+ +

La respuesta

+ +

La respuesta a la petición se muestra abajo. El código de estado "302 Found" le dice al explorador que el POST ha tenido éxito, y que debe realizar una segunda petición HTTP para cargar la página especificada en el campo Location. La información es de lo contrario similar a la respuesta a una petición GET.

+ +
HTTP/1.1 302 FOUND
+Server: Apache
+X-Backend-Server: developer3.webapp.scl3.mozilla.com
+Vary: Cookie
+Vary: Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:38:13 GMT
+Location: https://developer.mozilla.org/en-US/profiles/hamishwillee
+Keep-Alive: timeout=5, max=1000
+Connection: Keep-Alive
+X-Frame-Options: DENY
+X-Cache-Info: not cacheable; request wasn't a GET or HEAD
+Content-Length: 0
+
+ +
+

Nota: Las repuestas y las peticiones HTTP mostradas en estos ejemplos fueron capturadas usando la aplicación Fiddler, pero puedes obtener información similar usando sniffers web (ej. http://web-sniffer.net/) o usando extensiones del explorador como HttpFox. Puedes probarlo por tí mismo. Usa una de las herramientas enlazadas, y a continuación navega a través de un sitio y edita información del perfil para ver las diferentes peticiones y respuestas. La mayoría de los exploradores modernos también tienen herramientas que monitorizan las peticiciones de red (Por ejemplo, la herramienta Network Monitor en Firefox).

+
+ +

Sitios estáticos

+ +

Un sitio estático es aquél que devuelve desde el servidor el mismo contenido establecido de forma fija en el código cada vez que se solicita una página en particular. De manera que si por ejemplo tienes una página sobre un producto en /static/myproduct1.html , a todos los usuarios se les devolverá la misma página. Si añades otro producto similar a tu sitio necesitarás añadir otra página (ej. myproduct2.html) etc... Esto puede llegar a ser realmente muy poco eficiente — ¿qué sucede cuando alcanzas miles de páginas de productos? Repetirías un montón de código a lo largo de cada página (la plantilla básica de la página, la estructura, etc), y si quisieras cambiar cualquier cosa de la estructura de la página — como añadir una nueva sección de "productos relacionados" por ejemplo — tendrías que cambiar cada página individualmente. 

+ +
+

Nota: Los sitios estáticos son excelentes cuando tienes un pequeño número de páginas y quieres enviar el mismo contenido a todos los usuarios. Sin embargo pueden tener un coste de mantenimiento significante a medida que es número de páginas se hace grande.

+
+ +

Recapitulemos cómo funciona ésto, mirando otra vez el diagrama de la arquitectura de un sitio estático que vimos en el anterior artículo.

+ +

A simplified diagram of a static web server.

+ +

Cuando un usuario quiere navegar a una página, el explorador envía una petición HTTP GET especificando la URL de su página HTML. El servidor recupera el documento solicitado de su sistema de ficheros y devuelve una respuesta HTTP conteniendo el documento y un código de estado de respuesta HTTP "200 OK" (indicando éxito). El servidor podría devolver un código de estado diferente, por ejemplo "404 Not Found" si el fichero no está presente en el servidor, o "301 Moved Permanently" si el fichero existe pero ha sido redirigido a una localización diferente.

+ +

El servidor de un sitio estático sólo tendrá que procesar peticiones GET, ya que el servidor no almacena ningún dato modificable. Tampoco cambia sus respuestas basádonse en los datos de la petición HTTP (ej. parámetros URL o cookies). 

+ +

Entendiendo cómo funcionan los sitios estáticos es útil sin embargo cuando se aprende programación de lado servidor, porque los sitios dinámicos gestionan las peticiones de ficheros estáticos (CSS, JavaScript, imágenes estáticas, etc.) exactamente de la misma forma.

+ +

Sitios dinámicos

+ +

Un sitio dinámico es aquél que puede generar y devolver contenido basándose en la URL y los datos específicos de la petición (en vez de devolver siempre para una URL en particular el mismo fichero especificado en el código de forma fija). Usando el ejemplo de un sitio de productos, el servidor almacenaría "datos" del producto en una base de datos en vez de ficheros HTML individuales. Cuando se reciba una petición HTTP GET para un producto, el servidor determina el ID del mismo, extrae los datos de la base y construye la página HTML de la respuesta insertando los datos dentro de la plantilla HTML. Esto tiene una ventaja primordial sobre un sitio estático: 

+ +

Usar una base de datos permite que la información del producto se almacene de forma eficiente y que se pueda ampliar, modificar y buscar fácilmente.

+ +

Usar plantillas HTML hace que sea muy fácil cambiar la estructura HTML, porque sólo se necesita hacer en un sólo lugar, en una única plantilla y no a lo largo de miles de páginas estáticas.

+ +

Anatomía de una petición dinámica

+ +

Esta sección proporciona una visión general paso a paso de un ciclo de petición y respuesta HTTP "dinámicas", construyendo con más detalle lo que vimos en el último artículo. Para "hacer cosas reales" usaremos el contexto del sitio web de un manager de equipos deportivos donde un entrenador puede seleccionar el nombre y tamaño de su equipo en un formulario HTML y obtener de vuelta una sugerencia de "mejor alineación" para el próximo partido. 

+ +

El diagrama de abajo muestra los elementos principales del sitio web del "entrenador del equipo", junto con etiquetas numeradas de la secuencia de operaciones cuando el entrenador accede a su lista de "mejor equipo". Las partes del sitio que lo hacen dinámico son las Aplicaciones Web (que es como llamaremos al código del lado servidor que procesa las peticiones HTTP y devuelve respuestas HTTP), la Base de Datos, que contiene la información sobre los jugadores, equipos, entrenadores y sus relaciones, y las Plantillas HTML.

+ +

This is a diagram of a simple web server with step numbers for each of step of the client-server interaction.

+ +

Después de que el entrenador envíe el formulario con el nombre del equipo y el número de jugadores, la secuencia de operaciones es la siguiente:

+ +
    +
  1. El explorador web crea una petición HTTP GET al servidor usando la URL base del recurso (/best) y codifica el equipo y número de jugadores como parámetros URL (ej. /best?team=my_team_name&show=11) o formando parte de un patrón URL (ej. /best/my_team_name/11/). Se usa una petición GET porque la petición sólo recoge datos (no modifica ninguno).
  2. +
  3. El Servidor Web detecta que la petición es "dinámica" y la reenvía a la Aplicación para que la procese (el servidor web determina como manejar diferentes URLs basándose en reglas de emparejamiento de patrones definidas en su configuración).
  4. +
  5. La Aplicación Web identifica que la intención de la petición es obtener la "lista del mejor equipo" basándose en la URL (/best/) y encuentra el nombre del equipo y el número de jugadores requeridos a partir de la URL. La Aplicación Web obtiene entonces la información solicitada de la base de datos (usando parámetros "internos" adicionales que definen qué jugadores son los "mejores", y posiblemente también obteniendo la identidad del entrenador que ha iniciado sesión a partir de un cookie del lado cliente).
  6. +
  7. La Aplicación Web crea dinámicamente una página HTML por medio de colocar los datos (de la base) en marcadores de posición dentro de la plantilla HTML.
  8. +
  9. La Aplicación Web devuelve el HTML generado al explorador web (via el Servidor Web), junto con un código de estado HTTP de 200 ("éxito"). Si algo impide que se pueda devolver el HTML entonces la Aplicación Web devolverá otro código — por ejemplo "404" para indicar que el equipo no existe.
  10. +
  11. El Explorador Web comenzará a continuación a procesar el HTML devuelto, enviando peticiones separadas para obtener cualquier otro fichero CSS o JavaScript que sea referenciado (ver paso 7).
  12. +
  13. El Servidor Web carga ficheros estáticos del sistema de ficheros y los devuelve al explorador directamente (de nuevo, la gestión correcta de los ficheros está basada en las reglas de configuración y de emparejamiento de patrones URL).
  14. +
+ +

La operación de actualizar un registro de la base de datos se gestionaría de forma similar, excepto que, como para cualquier actualización de la base de datos, la petición HTTP desde el explorador debería ser codificada como petición POST

+ +

Realización de otros trabajos

+ +

La misión de una Aplicación Web es recibir peticiones HTTP y devolver respuestas HTTP. Mientras que interactuar con la base datos para obtener o actualizar información son tareas muy comunes, el código puede hacer otras cosas al mismo tiempo, o no interactuar con una base de datos en absoluto.

+ +

Un buen ejemplo de una tarea adicional que una  Aplicación Web podría realizar sería el envío de un correo electrónico a los usuarios para confirmar su registro en el sitio. El sito podría también realizar logging u otras operaciones.

+ +

Devolución de alguna otra cosa distinta a HTML

+ +

El código lado servidor de un sitio web no tiene que devolver fragmentos/ficheros HTML en la respuesta. Puede en vez de eso crear dinámicamente y devolver otros tipos de ficheros (texto, PDF, CSV, etc.) o incluso datos (jSON, XML, etc.).

+ +

La idea de devolver datos a un explorador web de forma que pueda actualizar su propio contenido dinámicamente ({{glossary("AJAX")}}) ha estado dando vueltas durante bastante tiempo. Más recientemente han llegado a ser muy populares las "apps de una sola página", donde el sitio web entero está escrito con un solo fichero HTML que es actualizado dinámicamente cuando se necesita. Los sitios web creados usando este estilo de aplicación transfieren una gran parte del coste computacional desde el servidor al explorador web, y pueden dar como resultado sitios web que se comportan mucho más como aplicaciones nativas (con una respuesta rápida "highly responsive", etc.).

+ +

Los frameworks Web simplifican la programación de lado servidor

+ +

Los frameworks de lado servidor hacen mucho más fácil escribir código para gestionar las operaciones descritas más arriba.

+ +

Una de las operaciones más importantes que realizan es proporcionar mecanismos simples para mapear las URLs de diferentes recursos/páginas a funciones para su gestión específicas. Esto hace más fácil mantener separado el código asociado con cada recurso. Esto tiene también beneficios en términos de mantenimiento, ya que puedes cambiar la URL usada para entregar una característica particular en un sitio, sin tener que cambiar la función de gestión.

+ +

Por ejemplo, considera el siguiente código Django (Python) que mapea dos patrones URL a dos funciones de visualización. El primer patrón asegura que una petición HTTP con una URL de  /best sea pasada a la función llamada index() en el módulo views. En cambio, una petición que tiene el patrón "/best/junior", se pasará a la función de visualización junior().

+ +
# file: best/urls.py
+#
+
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    # example: /best/
+    url(r'^$', views.index),
+    # example: /best/junior/
+    url(r'^junior/$', views.junior),
+]
+ +
+

Nota: El primer parámetro en las funciones url() puede parecer un poco extraño (ej. r'^junior/$') porque usan una técnica de emparejamiento de patrones llamada "expresiones regulares" ("regular expressions", RegEx, o RE). No necesitas saber cómo funcionan las expresiones regulares en este momento, tan sólo que nos permiten emparejar patrones en el URL (en vez de los valores insertados en el código de forma fija que veíamos más arriba) y los usan como parámetros en nuestras funciones de visualización. Como ejemplo, una RegEx simple podría decir "empareja una simple letra mayúscula, seguida de entre 4 y 7 letras minúsculas."

+
+ +

El framework web también hace fácil a una función de visualización extraer información de la base de datos. La estructura de nuestros datos está definida en modelos, que son las clases Python que definen los campos que serán almacenados en la base de datos subyacente. Si tenemos un modelo llamado Team con un campo de "team_type" podemos usar un query de sintaxis simple para recuperar todos los equipos que son de un tipo particular.

+ +

Los ejemplos de abajo recuperan una lista de todos los equipos que tienen el team_type de "junior" exacto (teniendo en cuenta la capitalización, mayúsculas o minúsculas) — nota de formato: el nombre del campo (team_type) seguido de un guión bajo doble, y a continuación el tipo de emparejamiento a usar (en este caso exact). Hay muchos otros tipos de emparejamiento y podemos encadenarlos fácilmente. Podemos controlar el orden y número de resultados que se devuelven. 

+ +
#best/views.py
+
+from django.shortcuts import render
+
+from .models import Team
+
+
+def junior(request):
+    list_teams = Team.objects.filter(team_type__exact="junior")
+    context = {'list': list_teams}
+    return render(request, 'best/index.html', context)
+
+ +

Después de que la función junior() obtenga la lista de equipos junior, llama a la función render(), pasándole el HttpRequest original,  una plantilla HTML, y un objeto "contexto" que define la información a ser incluida en la plantilla. La función render() es una función de conveniencia que genera HTML usando un contexto y una plantilla HTML, y devuelve un objeto HttpResponse.

+ +

Obviamente los frameworks web pueden ayudarte con un monton de otras tareas. Debatiremos sobre un montón más de beneficios y opciones de frameworks web en el próximo artículo.

+ +

Sumario

+ +

En este punto deberías tener una buena visión general de las operaciones que el código de lado servidor tiene que realizar, y conocer algunas de las formas en que un framework web de lado servidor las puede hacer más fáciles.

+ +

En el módulo siguiente te ayudaremos a elegir el mejor Framework Web para tu primer sitio.

+ +

{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}

+ +

 

+ +

En este módulo

+ + + +

 

diff --git a/files/es/learn/server-side/primeros_pasos/web_frameworks/index.html b/files/es/learn/server-side/primeros_pasos/web_frameworks/index.html new file mode 100644 index 0000000000..8c381a772e --- /dev/null +++ b/files/es/learn/server-side/primeros_pasos/web_frameworks/index.html @@ -0,0 +1,306 @@ +--- +title: Frameworks Web de lado servidor +slug: Learn/Server-side/Primeros_pasos/Web_frameworks +tags: + - Aprendizaje + - Codificación de scripts + - Frameworks web + - Guía + - Principiante + - Programación lado servidor + - Servidor + - introducción +translation_of: Learn/Server-side/First_steps/Web_frameworks +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}
+ +

El artículo anterior te mostró que pinta tiene la comunicación entre los clientes web y los servidores, la naturaleza de las peticiones y respuestas HTTP, y lo que necesita hacer una aplicación web de lado servidor para responder a las peticiones de un explorador web. Con este conocimiento en nuestra mochila, es hora de explorar cómo los frameworks web pueden simplificar estas tareas, y darte una idea de cómo escogerías un framework para tu primera aplicación web de lado servidor.

+ + + + + + + + + + + + +
Prerequisitos: +

Conocimientos de computación básicos. Comprensión de alto nivel de cómo gestiona y responde a las peticiones HTTP el código de lado servidor (ver Visión general Cliente-Servidor).

+
Objetivo: +

Entender cómo los frameworks web pueden simplificar el desarrollo/mantenimiento de código de lado servidor y conseguir que los lectores piensen sobre la elección del framework para su propio desarrollo.

+
+ +

Las siguientes secciones ilustran algunos puntos usando fragmentos de código tomados de frameworks web reales. No te preocupes si no todo tiene sentido ahora; te pondremos a trabajar sobre el código en nuestros módulos de framework específicos.

+ +

Visión general

+ +

Los frameworks de lado servidor (es decir, "los frameworks de aplicaciones web") son frameworks software que hacen más fácil escribir, mantener y escalar aplicaciones web. Proporcionan herramientas y bibliotecas que simplifican tareas comunes de desarrollo web, incluyendo enrutado de URLs a los manejadores apropiados, interactuación con bases de datos, soporte de sesiones y autorizaciones de usuario, formateado de la salida (ej, HTML, JSON, XML), y mejora de la seguridad contra los ataques web.

+ +

La sección siguiente proporciona un poco más detalle sobre cómo los frameworks web pueden facilitar el desarrollo de aplicaciones web. Explicaremos a continuación algunos de los criterios que puedes usar para elegir un framework web, y luego hacer una lista de algunas de tus opciones.

+ +

¿Qué puede hacer por tí un framework web?

+ +

Los frameworks web proporcionan herramientas y bibliotecas para simplificar operaciones comunes de desarrollo web. No tienes que usar un framework web de lado servidor, pero se recomienda encarecidamente — te hará la vida mucho más fácil.

+ +

Esta sección debate algo de la funcionalidad que proporcionan con frecuencia los frameworks web (!no todo framework proporcionará necesariamente todas estas caracteríticas!)

+ +

Trabajar directamente con peticiones y respuestas HTTP

+ +

Como vimos en el último artículo, los servidores web y los exploradores se comunican vía el protocolo HTTP — los servidores esperan las peticiones HTTP del explorador y devuelven información en respuestas HTTP. Los frameworks web te permiten escribir sintaxis simplificada que generará el código de lado servidor para trabajar con estas peticiones y respuestas. Esto significa que tendrás un trabajo más fácil, interacción más fácil, código de más alto nivel en vez de primitivas de red de bajo nivel.

+ +

El ejemplo de más abajo muestra cómo funciona ésto en el framework web Django (Python). Cada función de visualización "view" (un manejador de peticiones) recibe un objeto HttpRequest que contiene información de petición, y se le pide devolver un objeto HttpResponse con la salida formateada (en este caso una cadena de texto).

+ +
# Django view function
+from django.http import HttpResponse
+
+def index(request):
+    # Get an HttpRequest (request)
+    # perform operations using information from the request.
+    # Return HttpResponse
+    return HttpResponse('Output string to return')
+
+ +

Enrutado de peticiones al manejador adecuado

+ +

La mayoría de sitios proporcionan un gran número de recursos diferentes, accesibles a través de distintas URLs. La gestión de todo esto en una sola función sería difiicil de mantener, de manera que los frameworks web proporcionan mecanismos simples para mapear patrones URL a funciones de gestión específicas. Esta aproximación tiene también beneficios en términos de mantenimiento, porque puedes cambiar el URL que se usa para entregar una característica en particular sin tener que cambiar el código subyacente.

+ +

Diferentes frameworks usan diferentes mencanismos para el mapeo. Por ejemplo, el framework web Flask (Python) añade rutas a las funciones de visualización usando un "decorador".

+ +
@app.route("/")
+def hello():
+    return "Hello World!"
+ +

Por el contrario Django espera que los desarrolladores definan una lista de mapeos URL entre un patrón URL y una función de visualización.

+ +
urlpatterns = [
+    url(r'^$', views.index),
+    # example: /best/myteamname/5/
+    url(r'^(?P<team_name>\w.+?)/(?P<team_number>[0-9]+)/$', views.best),
+]
+
+ +

Fácil acceso a los datos en la petición

+ +

Los datos pueden codificarse en una petición HTTP de muchas maneras. Una petición GET para recuperar ficheros o datos de un servidor puede codificar los datos que se necesitan en parámetros URL o dentro de una estructura URL. Una petición POST para actualizar un recurso en el servidor puede en cambio incluir la información de actualización como "datos POST" dentro del cuerpo de la petición. La petición HTTP puede también incluir información sobre la sesión o usuario actual en un cookie de lado cliente.

+ +

Los frameworks web proporcionan mecanismos apropiados del lenguaje de programación para acceder a esta información. Por ejemplo, el objeto HttpRequest  que pasa Django a toda función de visualización contiene métodos y propiedades para acceder a la URL de destino, el tipo de petición (ej. HTTP GET), parámetros GET  o POST, cookie y datos de session, etc. Django puede también pasar información codificada en la estructura de la URL definiendo "patrones de captura" en el mapeador URL (mira el último fragmento de código de la sección de arriba).

+ +

Abstraer y simplificar el acceso a bases de datos

+ +

Los sitios web utilizan bases de datos para almacenar información tanto para ser compartida con los usuarios como sobre los propios usuarios. Los frameworks web proporcionan frecuentemente una capa de base de datos que abstrae las operaciones de lectura, escritura, consulta y borrado de la base. Nos referimos a esta capa de abstracción como Mapeador de Objetos Relacionados (Object-Relational Mapper, ORM).

+ +

Usar un ORM tiene dos beneficios:

+ + + +

Por ejemplo, el framework web de Django proporciona un ORM, y utiliza la referencia del objeto usado para definir la estructura de un registro similar al modelo. El modelo especifica los tipos de campos que se almacenarán, lo que puede proporcionar una validación a nivel de campo sobre qué información se puede guardar (ej. un campo de email sólo permitiría direcciones válidas de correo electrónico). Las definiciones de campos pueden también especificar su tamaño máximo, etiquetas de texto para los formularios, etc. El modelo no establece ninguna información sobre la base de datos subyacente ya que ese es un ajuste de configuración que se puede cambiar de forma separada de nuestro código.

+ +

El primer fragmento de código más abajo muestra un modelo de Django muy simple para un objeto Team. Éste almacena el nombre y nivel del equipo como campos de caracteres y especifica el número máximo de éstos que pueden almacenarse en cada registro. El team_level es un campo de selección, de manera que proporcionamos un mapeo entre las opciones a mostrar en pantalla y los datos a almacenar, junto con un valor por defecto.

+ +
#best/models.py
+
+from django.db import models
+
+class Team(models.Model):
+    team_name = models.CharField(max_length=40)
+
+    TEAM_LEVELS = (
+        ('U09', 'Under 09s'),
+        ('U10', 'Under 10s'),
+        ('U11, 'Under 11s'),
+        ...  #list our other teams
+    )
+    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+
+ +

El modelo de Django proporciona una API de consulta simple para buscar en la base de datos. Ésta puede comprobar coincidencias contra un gran número de campos al mismo tiempo usando diferentes criterios (ej. exacto, insensible a las mayúsculas, mayor que, etc.), y puede soportar sentencias complejas (por ejemplo, puedes especificar una búsqueda de equipos U11 que tengan un nombre de equipo que empiece por "Fr" or finalice con "al").

+ +

El segundo fragmento de código muestra una función de visualización (manejador de recurso) para mostrar en pantalla todos nuestros equipos U09. En este caso especificamos que queremos filtrar todos los registros donde el campo team_level tenga exactamente el texto 'U09' (fíjate debajo cómo este criterio se pasa como argumento a la función filter() con el nombre de campo y tipo de coincidencia separados por guiones bajos dobles: team_level__exact).

+ +
#best/views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def youngest(request):
+    list_teams = Team.objects.filter(team_level__exact="U09")
+    context = {'youngest_teams': list_teams}
+    return render(request, 'best/index.html', context)
+
+ +
+
+ +

Renderización de datos

+ +

Los frameworks web proporcionan con frecuencia sistemas de plantillas. Éstas te permiten especificar la estructura de un documento de salida, usando marcadores de posición para los datos que serán añadidos cuando se genere la página. Las plantillas se usan con frecuencia para crear HTML, pero también pueden crear otros tipos de documentos.

+ +

Los frameworks web proporcionan con frecuencia un mecanismo para facilitar la generación de otros formatos a partir de los datos almacenados, incluyendo {{glossary("JSON")}} y {{glossary("XML")}}.

+ +

Por ejemplo, el sistema de plantillas de Django te permite especificar variables usando una sintaxis de "llaves dobles" (ej. {{ variable_name }}),  que serán reemplazadas por valores pasados desde la función de visualización cuando la página sea renderizada. El sistema de plantillas también proporciona soporte para expresiones (con la sintaxis: {% expression %}), que permite a las plantillas realizar operaciones simples como iterar sobre la lista de valores pasados a la misma.

+ +
+

Nota: Muchos otros sistemas de plantillas usan una sintaxis similar, ej.: Jinja2 (Python), Handlebars (JavaScript), Moustache (JavaScript), etc.

+
+ +

El fragmento de código de abajo muestra como hacer este trabajo. Continuando el ejemplo del "equipo más joven" de la sección anterior, la "view" pasa a la plantilla HTML una variable tipo lista llamada youngest_teams. Dentro del esqueleto HTML tenemos una expresión que primero comprueba que la variable youngest_teams existe, y luego itera sobre ella en un bucle for. En cada iteración la plantilla presenta en pantalla el valor del team_name  del equipo de uno de los elementos de la lista.

+ +
#best/templates/best/index.html
+
+<!DOCTYPE html>
+<html lang="en">
+<body>
+
+ {% if youngest_teams %}
+    <ul>
+    {% for team in youngest_teams %}
+        <li>\{\{ team.team_name \}\}</li>
+    {% endfor %}
+    </ul>
+{% else %}
+    <p>No teams are available.</p>
+{% endif %}
+
+</body>
+</html>
+
+ +

Como escoger un framework web

+ +

Existen muchos frameworks web para casi todos los lenguajes de programación que quieras usar (listamos unos pocos de los frameworks más populares en la sección siguiente). Con tantas opciones, llega a ser difícil deducir qué framework proporciona el mejor punto de partida para tu nueva aplicación web. 

+ +

Algunos de los factores que pueden afectar tu decisión son:

+ + + +

Hay muchos otros posibles factores, incluyendo licenciamiento, si el framework está bajo desarrollo activo o no, etc.

+ +

Si eres un completo principiante en la programación probablemente escogerás tu framework basándote en la "facilidad de aprendizaje". Además de la "facilidad de uso" del lenguaje mismo, la alta calidad de la documentación/tutoriales y una comunidad activa que ayuda a nuevos usuarios son tus recursos más valiosos. Nosotros hemos escogido Django (Python) y Express (Node/JavaScript) para escribir nuestros ejemplos de más adelante en el curso, principalmente porque son fáciles de aprender y tienen un buen soporte.

+ +
+

Nota: Vayamos a los sitios principales de Django (Python) y Express (Node/JavaScript) y comprobemos su documentación y su comunidad.

+ +
    +
  1. Navega a los sitios principales (enlazados abajo) +
      +
    • Pincha en los enlaces de los menus de Documentación (cosas que se llaman como "Documentación, Guía, Referencia API, Primeros Pasos".
    • +
    • ¿Puedes ver temas que te muestran como configurar enrutado URL, plantillas y bases de datos/modelos?
    • +
    • ¿Son los documentos suficientemente claros?
    • +
    +
  2. +
  3. Navega a las listas de correo de cada sitio (accesible desde los enlaces de Comunidad). +
      +
    • ¿Cuántas preguntas se han realizado en unos pocos días recientes?
    • +
    • ¿Cuántas tienen respuestas?
    • +
    • ¿Tienen una comunidad activa?
    • +
    +
  4. +
+
+ +

¿Unos pocos frameworks web buenos?

+ +

Avancemos ahora, y debatamos unos pocos frameworks web específicos de lado servidor.

+ +

Los frameworks de lado servidor de más abajo representan unos pocos de los más populares disponibles en el momento de escribir este artículo. Todos ellos tienen todo lo que necesitas para ser productivo — son de código abierto, están bajo desarrollo activo, tienen comunidades entusiastas creando documentación y ayudando a los usuarios en paneles de debate, y se usan en un gran número de sitios web de perfil alto. Hay muchos otros frameworks de lado servidor fantásticos que puedes descubrir usando una búsqueda básica en internet. 

+ +
+

Nota: ¡Las descripciones vienen (parcialmente) de los sitios web de los frameworks!

+
+ +

Django (Python)

+ +

Django es un Framework Web Python de alto nivel que promueve el desarrollo rápido y limpio y el diseño pragmático. Construido por desarrolladores experimentados, tiene en cuenta muchos de los problemas del desarrollo web, de manera que puedes focalizarte en escribir el código de tu app sin necesidad de reinventar la rueda. Es gratis y de código abierto.

+ +

Django sigue la filosofía de "Baterias incluidas" y proporciona casi todo lo que la mayoría de desarrolladores querría hacer "de fábrica". Como todo está incluido, todo funciona en conjunto, sigue principios de diseño consistentes y tiene una extensa documentación actualizada. Es también veloz, seguro y muy escalable. Al estar basado en Python, el código de Django es fácil de leer y de mantener.

+ +

Entre los sitios populares que usan Django (según su página web) se incluyen: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, Open Stack.

+ +

Flask (Python)

+ +

Flask es un microframework para Python. 

+ +

A pesar de ser minimalista, Flask puede crear sitios web "de fábrica". Contiene un servidor de desarrollo y depurador, e incluye soporte para plantillas Jinja2, cookies seguros, prueba de unidades, y distribución de peticiones RESTful. Tiene  buena documentación y una comunidad activa. 

+ +

Flask se ha vuelto extremadamente popular, particularmente entre desarrolladores que necesitan proporcionar servicios web en sistemas pequeños, y con recursos escasos (ej. ejecutar un servidor web en una  Raspberry Pi, Controladores de Drones, etc.)

+ +

Express (Node.js/JavaScript)

+ +

Express es un framework web veloz, no dogmático, flexible y minimalista para Node.js (Node es un entorno sin explorador web para ejecutar JavaScript). Proporciona un conjunto de características robusto para aplicaciones web y móviles y entrega valiosos métodos de utilidades HTTP y middleware.

+ +

Express es extremadamente popular, en parte porque facilita la migración de programadores web de JavaScript de lado cliente a desarrollo de lado servidor, y en parte porque es eficiente con los recursos (el entorno de node subyacente usa multitarea ligera dentro de un thread en vez de expandirse en procesos separados para cada nueva petición web).

+ +

Debido a que Express es un framework web minimalista no incorpora cada componente que querrías usar (por ejemplo, el acceso a bases de datos y el soporte de usuarios y sesiones se proporciona a través de bibliotecas independientes). Hay muchos componentes independientes excelentes, !pero algunas veces puede ser difícil deducir cuál es el mejor para un propósito en particular!

+ +

Muchos frameworks populares y completamente equipados (incluyendo ambos tipos de frameworks de lado servidor y de lado cliente) están basados en Express, como FeathersItemsAPIKeystoneJSKrakenLEAN-STACKLoopBackMEAN, and Sails.

+ +

Un montón de compañías de perfil alto usan Express, como: Uber, Accenture, IBM, etc. (aquí tienes una lista).

+ +

Ruby on Rails (Ruby)

+ +

Rails (normalmente referenciado como "Ruby on Rails") es un framework web escrito para el lenguaje de programación Ruby.

+ +

Rails sigue una filosofía de diseño muy similar a Django. Como Django proporciona mecanismos estándard para el enrutado de URLs, acceso a datos de bases, generación de plantillas y formateo de datos como {{glossary("JSON")}} o {{glossary("XML")}}. Promueve de forma similar el uso de patrones de diseño como DRY ("dont repeat yourself", no te repitas — escribir el código una única vez si es posible), MVC (model-view-controller) y numerosos otros.

+ +

Hay por supuesto muchas diferencias debido a decisiones específicas de diseño y la naturaleza de los lenguajes.

+ +

Rails se usa en sitios de perfil alto, como: BasecampGitHubShopifyAirbnbTwitchSoundCloudHuluZendeskSquareHighrise.

+ +

ASP.NET

+ +

ASP.NET es un framework web de código abierto desarrollado por Microsoft para construir aplicaciones y servicios modernos. Con ASP.NET puedes crear rápidamente sitios web basados en HTML, CSS, y JavaScript, escalarlos para ser usados por milllones de usuarios y añadir fácilmente capacidades complejas como APIs web, formularios sobre datos o comunicaciones en tiempo real.

+ +

Uno de los diferenciadores de ASP.NET es que está construido sobre el Common Language Runtime (CLR), permitiendo a los programadores escribir código ASP.NET usando cualquier lenguaje .NET soportado (C#, Visual Basic, etc.). Como muchos productos Microsoft se beneficia de herramientas excelentes (frecuentemente gratuitas), y una comunidad de desarrolladores activa, y documentación bien escrita.

+ +

ASP.NET se usa por Microsoft, Xbox.com, Stack Overflow, y muchos otros.

+ +

Mojolicious (Perl)

+ +

Mojolicious es un framework web de nueva generación para el lenguaje de programación Perl.

+ +

Hace tiempo en los primeros días de la Web, mucha gente aprendió Perl gracias a una magnífica biblioteca llamada CGI. Era lo suficientemente simple para empezar sin saber mucho sobre el lenguaje y lo suficientemente potente para mantenerte en marcha. Mojolicious implementa esta idea usando el último grito de las tecnologías.

+ +

Algunas de las caracteríticas que proporciona Mojolicious son: Framework Web en tiempo real, para crecer fácilmente desde prototipos de un solo fichero hasta aplicaciones web MVC bien estructuradas; rutas RESTful, plugins, comandos, plantillas especificas de Perl, negociación de contenidos, gestión de sesiones, validación de formatos, framework de pruebas, servidor de ficheros estáticos, detección de CGI/PSGI, soporte Unicode de primera clase; Implementación  cliente/servidor completamente equipada de HTTP y WebSocket con IPv6, TLS, SNI, IDNA, HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), keep-alive, connection pooling, timeout, cookie, y soporte de compresión multipart y gzip; parseadores JSON y HTML/XML y generadores con soporte de selector CSS; Muy limpio, portable y API orientada a objetos y Perl puro sin magia oculta; Código fresco basado en años de experiencia, gratis y de código abierto.

+ +

Sumario

+ +

Este artículo ha mostrado que los frameworks web pueden hacer fácil el desarrollo y mantenimiento del código de lado servidor. También ha proporcionado una visión general de alto nivel de unos pocos frameworks más populares y debatido los criterios para elegir el framework para una aplicación web. Deberías tener en este momento una idea de cómo elegir un framework web para tu propio desarrollo de lado servidor. Si no, no te preocupes — más tarde a lo largo del curso te daremos tutoriales detallados de Django y Express para darte algo de experiencia de funcionamiento real con un framework web.

+ +

Para el próximo artículo de este módulo cambiaremos de dirección ligeramente y consideraremos la seguridad web.

+ +

{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}

+ +

 

+ +

En este modulo

+ + + +

 

diff --git a/files/es/learn/using_github_pages/index.html b/files/es/learn/using_github_pages/index.html new file mode 100644 index 0000000000..81a7138430 --- /dev/null +++ b/files/es/learn/using_github_pages/index.html @@ -0,0 +1,103 @@ +--- +title: ¿Cómo se utiliza Github pages? +slug: Learn/Using_Github_pages +translation_of: Learn/Common_questions/Using_Github_pages +--- +

GitHub es un sitio "social coding". Te permite subir repositorios de código para almacenarlo en el sistema de control de versiones Git. Tu puedes colaborar en proyectos de código, y el sistema es código abierto por defecto, lo que significa que cualquiera en el mundo puede encontrar tu código en GitHub, usarlo, aprender de el, y mejorarlo. ¡Tú puedes hacer eso con el código de otras personas tambien! Este artículo provee una guía básica para publicar contenido usando la característica gh-pages de Github.

+ +

Publicando contenido

+ +

Github es una comunidad muy importante y útil para involucrarse, y Git/GitHub es un sistema de control de versiones muy popular — la mayoría de las empresas de tecnología ahora lo utilizan en su flujo de trabajo. GitHub tiene una característica muy útil llamada GitHub pages, que te permite publicar el código del sitio en vivo en la Web.

+ +

Configuración básica de Github

+ +
    +
  1. Primero que todo, instala Git en tu máquina. Este es el software del sistema de control de versiones subyacente en el que GitHub funciona.
  2. +
  3. Seguido, Regístrate para una cuenta de GitHub. Es simple y fácil.
  4. +
  5. Una vez te hayas registrado, inicia sesión en github.com con tu nombre de usuario y contraseña.
  6. +
+ +

Preparando tu código para subirlo

+ +

Tú puedes almacenar cualquier código que tu quieras en un repositorio de Github, pero para usar la característica páginas de Github con pleno efecto, tu código debe estar estructurado como un sitio web típico, por ejemplo que el punto de entrada primario sea un archivo HTML llamado index.html.

+ +

La otra cosa que necesitas hacer antes de seguir adelante es inicializar el directorio de código como un repositorio Git. para hacer esto:

+ +
    +
  1. Apunta la línea de comandos a tu directorio test-site (o como se llame el directorio que contiene tu sitio web). Para esto, usa el comando cd (Es decir "cambio de directorio"). Esto es lo que deberías digitar si has puesto tu sitio web en un directorio llamado test-site en tu escritorio: + +
    cd Desktop/test-site
    +
  2. +
  3. Cuando la línea comandos está apuntando hacia el interior del directorio de tu sitio web, digita el siguiente comando, que le dice a la herramienta git para convertir el directorio en un repositorio git:
  4. +
  5. +
    git init
    +
  6. +
+ +

An aside on command line interfaces

+ +

La mejor manera de subir tu código a Github es mediante la linea de comandos — esta es una ventana donde tú escribe comandos para hacer cosas como crear archivos y ejecutar programas, en lugar de hacer clic dentro de una interfaz de usuario. Se verá algo como esto:

+ +

+ +
+

Nota: Tú también podrías considerar una interfaz gráfica de usuario de Git para hacer el mismo trabajo, si te sientes incómodo con la linea de comandos.

+
+ +

Cada sistema operativo viene con una herramienta de línea de comandos:

+ + + +

Esto puede parecer un poco espantoso al principio, pero no te preocupes — que pronto conseguiras la caída de los conceptos básicos. Tú le dices a la computadora que haga algo en la terminal, digitando un comando y oprimiendo la tecla Enter, como se ha visto anteriormente.

+ +

Creando un repositorio para tu código

+ +
    +
  1. +

    A continuación, tu necesitas crear un nuevo repositorio para colocar tus archivos en el. Has clic en el signo más (+) en la parte superior derecha de la página de inicio de GitHub, luego escoge Nuevo Repositorio.

    +
  2. +
  3. En esta página, en la caja Nombre del Repositorio, digita el nombre para tu repositorio de código, por ejemplo my-repository.
  4. +
  5. También llena una descripción para decir lo que tu repositorio va a contener. Tu pantalla debe mostrar algo como esto:
    +
  6. +
  7. Has Clic en Crear repositorio; Esto debería llevarte a la siguiente página: 
    +
  8. +
+ +

Subiendo tus archivos a GitHub

+ +
    +
  1. En la página actual, tú estás interesado en la sección …o empujar un repositorio existente desde la línea de comandos. Tú deberias ver dos lineas de código listado en esta sección. Copia la totalidad de la primera línea, pégala en la línea de comandos, presiona la tecla Enter. El comando debería mostrarte algo como esto: + +
    git remote add origin https://github.com/chrisdavidmills/my-repository.git
    +
  2. +
  3. A continuación, digita los siguientes dos comandos, presionando Enter despues de cada uno. Estos preparán el código para subirlo a GitHub, y pida a GIt que administre estos archivos. +
    git add --all
    +git commit -m 'adding my files to my repository'
    +
  4. +
  5. Por último, empuja el código hasta GitHub yendo a la página de GitHub en la que estas e ingresando en la terminal el segundo de los dos comandos que vimos …o empuje un repositorio existente desde la sección de línea de comandos: +
    git push -u origin master
    +
  6. +
  7. Ahora necesitas crear la rama gh-pages de tu repositorio; actualiza la página actual y verá una página del repositorio algo así como la de abajo. Tú necesitas presionar el boton que dice Branch: master, digita gh-pages en el campo de texto, luego presiona el boton azul que dice Create branch: gh-pages. Esto crea una rama de código especial llamada gh-pages que es publicada en una ubicación especial. La URL toma la forma username.github.io/my-repository-name, asi en mi caso de ejemplo, la URL debería ser https://chrisdavidmills.github.io/my-repository. La página mostrada es la página index.html.
    +
  8. +
  9. Navega tu dirección web de GitHub pages en un nuevo ta del navegador, y tu deberias ver tu sitio en linea! Mandalo por correo electrónico a tus amigos y muestra tu dominio.
  10. +
+ +
+

Nota: Si te atascas, la página de inicio de GitHub Pages también es muy útil.

+
+ +

Un mayor conocimiento de GitHub

+ +

Si deseas realizar más cambios en su sitio de prueba y cargarlos en GitHub, simplemente tendrás que realizar el cambio en tus archivos como antes. A continuación, debes introducir los siguientes comandos (pulsando Intro después de cada uno) para empujar los cambios a GitHub:

+ +
git add --all
+git commit -m 'another commit'
+git push
+ +

Puedes reemplazar otro commit con un mensaje más adecuado para describir qué cambio acaba de hacer.

+ +

Apenas hemos arañado la superficie de Git.Para obtener más información, comience con el sitio de ayuda de GitHub.

-- cgit v1.2.3-54-g00ecf