👋 ¡Hola! Queremos avisarle que el código fuente que acompaña a esta serie ya no está disponible para descargar. Todavía creemos que hay valiosos bits de información para obtener de la serie, pero dado que llevamos más de 10 años en el camino, también creemos que vale la pena considerar un marco PHP moderno (como Laravel) o incluso un marco JavaScript (como React o Vue) para crear una aplicación web progresiva.
¡Es hora de ensuciarnos las manos con algunas marcas!
Sabemos que tenemos un par de páginas diferentes de las que ocuparnos aquí. La página principal, por supuesto, que actúa como nuestra página de lista y página de ventas dependiendo del estado de inicio de sesión. Pero luego tenemos páginas de inicio de sesión y registro y páginas de cuenta. Así que seamos inteligentes y trabajemos en modularidad. Eso significa que crearemos archivos como “header.php” y “close.php” que podemos incluir en varias páginas para que no tengamos que repetir código común (por ejemplo, el DOCTYPE, el código analítico y cosas ubicuas como esa).
Serie de artículos
- Planificación de la aplicación: idea básica y diseño
- Planificación de la aplicación: arquitectura de base de datos y enfoque de desarrollo
- Diseño de la aplicación: mapa de flujo de trabajo y diseño de Photoshop
- Diseño de la aplicación: HTML y CSS
- Desarrollo de la aplicación: interacción del usuario
- Desarrollo de la aplicación: adición de interactividad AJAX
- Desarrollo de la aplicación: interacción de listas
- Seguridad y futuro
Organización raíz web
Esto es lo que tenemos para los archivos en la raíz de nuestro directorio web hasta ahora. Todas las vistas principales tienen sus propios archivos PHP. Tenemos subdirectorios para imágenes y archivos “comunes”. y tenemos algunos archivos sueltos como CSS y el favicon.
Nuestro desarrollador seguramente agregará más archivos. Necesitará archivos PHP para interactuar con la base de datos y realizar todas las interacciones de la lista.
Encabezamiento
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Colored Lists | <!-- Do Something Smart Here --></title>
<link rel="stylesheet" href="https://css-tricks.com/app-from-scratch-4-html-css/style.css" type="text/css" />
<link rel="shortcut icon" type="image/x-icon" href="https://css-tricks.com/favicon.ico" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2"></script>
</head>
<body>
<div id="page-wrap">
<div id="header">
<h1><a href="https://css-tricks.com/">Colored Lists</a></h1>
<div id="control">
<!-- IF LOGGED IN -->
<p><a href="https://css-tricks.com/logout.php" class="button">Log out</a> <a href="http://css-tricks.com/account.php" class="button">Your Account</a></p>
<!-- IF LOGGED OUT -->
<p><a class="button" href="https://css-tricks.com/signup.php">Sign up</a> <a class="button" href="http://css-tricks.com/login.php">Log in</a></p>
<!-- END OF IF STATEMENT -->
</div>
</div>
Inmediatamente en el encabezado nos encontramos con algunas cosas en las que debemos ser inteligentes y dejar notas para el desarrollador, pero darle las cosas que necesita. En el título de la página, dejamos una nota para hacer algo inteligente allí. Las diferentes páginas necesitan diferentes títulos de página, por lo que claramente debe suceder algo dinámico allí. Luego, con nuestros botones de control (por ejemplo, Cuenta / Cerrar sesión) esos botones serán diferentes dependiendo del estado de inicio de sesión del usuario. Así que dejaremos que el desarrollador intervenga y haga que esas cosas funcionen correctamente.
Entonces, en este punto, tenemos la parte superior de una página. Dejamos abiertos los elementos body, html y # page-wrap, ya que más allá de eso está el contenido principal de la página. Antes de entrar en ese contenido principal, agreguemos las áreas de la barra lateral y el pie de página para que tengamos un aspecto completo.
Pie de página
Nuestro diseño no requiere mucho pie de página, por lo que simplemente cerraremos esos elementos abiertos y agregaremos una nota para poner los análisis aquí.
</div>
<!-- Analytics here -->
</body>
</html>
Barra lateral
Nuestro diseño requiere un poco de barra lateral. En este momento, solo lo usaremos para algunas notas sobre el uso de la aplicación. Pero es bueno tener algo de espacio abierto para el contenido, ya que es muy probable que se necesite espacio para cosas adicionales a medida que la aplicación crece.
<div id="ribbon">
Reminders
<ul>
<li>Your list automatically saves</li>
<li>Double-click list items to edit them</li>
</ul>
</div>
Pagina principal
Ahora que tenemos nuestros “módulos” completos, profundicemos en una página real. La plantilla para construir cualquier página será así:
<?php include_once "common/header.php"; ?>
<div id="main">
<noscript>This site just doesn't work, period, without JavaScript</noscript>
<!-- IF LOGGED IN -->
<!-- Content here -->
<!-- IF LOGGED OUT -->
<!-- Alternate content here -->
</div>
<?php include_once "common/sidebar.php"; ?>
<?php include_once "common/footer.php"; ?>
Conectado (La lista)
<ul id="list">
<li class="colorRed">
<span>Walk the dog</span>
<div class="draggertab tab"></div>
<div class="colortab tab"></div>
<div class="deletetab tab"></div>
<div class="donetab tab"></div>
</li>
<li class="colorBlue">
<span>Pick up dry cleaning</span>
<div class="draggertab tab"></div>
<div class="colortab tab"></div>
<div class="deletetab tab"></div>
<div class="donetab tab"></div>
</li>
<li class="colorGreen">
<span>Milk</span>
<div class="draggertab tab"></div>
<div class="colortab tab"></div>
<div class="deletetab tab"></div>
<div class="donetab tab"></div>
</li>
</ul>
La lista en sí será simplemente una lista desordenada. Usaremos nombres de clases CSS para los colores. Pero luego necesitamos un montón de controles para los elementos de la lista. Eso es lo que todos esos divs están dentro de los elementos de la lista. Hay divs vacíos para arrastrar, cambiar de color, eliminar y marcar elementos de la lista. Los necesitamos para el CSS para poder orientarlos y diseñarlos.
Sin embargo, somos diseñadores inteligentes, sabemos que este marcado es simplemente temporal. Estas listas serán generadas dinámicamente por la aplicación. Solo mirando todos esos divs de control vacíos; sabemos que probablemente esos sean generados automáticamente por JavaScript. Está bien, necesitamos el HTML ahora para preparar el escenario y tener a todos en la misma página.
¿Por qué los intervalos dentro de los elementos de la lista? Solo siendo inteligente. Debido a que los elementos de la lista envuelven más que solo el texto, es probable que más adelante necesitemos algún tipo de gancho para apuntar solo al texto.
Ahora necesitamos obtener una entrada en esta página para agregar nuevos elementos de lista. Nuestro desarrollador estará en todo esto, pero pondremos los conceptos básicos para que podamos diseñarlos.
<form action="" id="add-new">
<div>
<input type="text" id="new-list-item-text" name="new-list-item-text" />
<input type="submit" id="add-new-submit" value="Add" class="button" />
</div>
</form>
Entonces, una de las características de nuestras aplicaciones es tener URL públicas compartibles para nuestras listas. Pongamos eso aquí también.
<div id="share-area">
<p>Public list URL: <a href="https://css-tricks.com/app-from-scratch-4-html-css/#">URL GOES HERE</a>
<small>(Nobody but YOU will be able to edit this list)</small></p>
</div>
¡Ahhh, más trabajo para el desarrollador! Pero está listo para eso. Este negocio de URL públicas nos lleva a otro escenario posible. Necesitamos que esta página principal sea capaz de mostrar una lista sin mostrar el formulario de entrada o todos los controles de la lista. Básicamente, puede mirar la lista pero no interactuar con ella. (¡Como si quisieras enviarle a tu mamá tu lista de Navidad!)
Desconectado (lista pública)
<ul id="list">
<li class="colorRed">
<span>Walk the dog</span>
</li>
<li class="colorBlue">
<span>Pick up dry cleaning</span>
</li>
<li class="colorGreen">
<span>Milk</span>
</li>
</ul>
Será exactamente igual a la lista anterior, solo que sin pestañas de control, sin formulario para agregar nuevos elementos y sin área de URL pública (oye, ya están aquí, para qué necesitan la URL). Sabemos que esto probablemente será solo un cambio en la forma en que el código de backend genera la lista. Pero sea lo que sea, si creamos esto, todos estarán en la misma página.
Desconectado (ventas)
Podríamos hacer algo elegante algún día para esto, pero por ahora, nuestra gran idea es solo un gráfico genial que muestre que esta área es potencialmente donde estará su nueva lista y una gran flecha que muestra a las personas dónde pueden registrarse.
<img src="https://css-tricks.com/images/newlist.jpg" alt="Your new list here!" />
Página de la cuenta
Como recordatorio rápido, usamos esta estructura para todas las páginas, incluida esta.
<?php include_once "common/header.php"; ?>
<div id="main">
<!-- IF LOGGED IN -->
<!-- Content here -->
<!-- IF LOGGED OUT -->
<!-- Alternate content here -->
</div>
<?php
include_once "common/sidebar.php";
include_once "common/footer.php";
?>
Esa es la belleza de trabajar de forma modular, todo el contenido común está incluido, por lo que las actualizaciones en el futuro son mucho más fáciles.
La página de la cuenta tendrá varios formularios: uno para actualizar el correo electrónico, otro para actualizar la contraseña y un botón para que los usuarios eliminen sus cuentas. Nuevamente, nuestro desarrollador estará en todos estos formularios llenándolos con entradas ocultas que transmiten datos y agregan URL de acción y métodos y todo eso. Eso se lo dejamos a él, pero esto nos da suficiente estilo.
<h2>Your Account</h2>
<form action="">
<div>
<input type="text" name="username" id="username" />
<label for="username">Change Email Address</label>
<input type="submit" name="change-email-submit" id="change-email-submit" value="Change Email" class="button" />
</div>
</form>
<hr />
<h2>Change Password</h2>
<form action="https://css-tricks.com/app-from-scratch-4-html-css/#">
<div>
<label for="password">New Password</label>
<input type="password" name="r" id="repeat-new-password" />
<label for="password">Repeat New Password</label>
<input type="submit" name="change-password-submit" id="change-password-submit" value="Change Password" class="button" />
</div>
</form>
<hr />
<form action="" id="delete-account-form">
<div>
<input type="submit" name="delete-account-submit" id="delete-account-submit" value="Delete Account?" class="button" />
</div>
</form>
Otras páginas de “formularios”
Ahora que hemos terminado con la página de la cuenta, hemos cubierto prácticamente todas las bases para las otras páginas de estilo de “formulario”. Regístrese, inicie sesión, olvidó su contraseña, todas son versiones más simples de la página de la cuenta. Dado que habremos diseñado el formato básico de etiqueta / entrada, el formato de encabezado y el formato de “botón”, el desarrollador puede crear fácilmente estas páginas él mismo copiando el formato básico y las clases CSS de la página de la cuenta.
El CSS
Reiniciar
/*
RESET
*/
* { margin: 0; padding: 0; }
body { font: 14px/1.1 Helvetica, Sans-Serif; background: url(images/stripe.png) repeat-x; }
.clear { clear: both; }
img, a img { border: none; }
input { outline: none; }
Solo limpiando las cosas.
Estructura
/*
STRUCTURE
*/
body { font: 14px/1.1 Helvetica, Sans-Serif; background: url(images/stripe.png) repeat-x; }
#page-wrap { width: 960px; margin: 6px auto 50px; position: relative; }
hr { height: 1px; background: #ccc; clear: both; margin: 20px 0; border: none; display: block; }
Formato no demasiado complicado para nuestra pequeña aplicación de una página.
Tipografía
/*
TYPOGRAPHY
*/
a { text-decoration: none; color: #900; border-bottom: 1px dotted #900; outline: none; }
h1 { font: bold 36px Helvetica, Sans-Serif; margin: 0 0 8px 0; }
h2 { margin: 0 0 10px 0; }
p { margin: 0 0 6px 0; }
.button { background: url(/images/button-bg.png) repeat-x; -moz-border-radius: 5px; padding: 6px 12px; border: none; color: white; cursor: pointer; text-shadow: 0 1px 1px #666; -webkit-border-radius: 5px; -webkit-box-shadow: 0 1px 3px #999; -moz-box-shadow: 0 1px 3px #999; font: bold 16px Helvetica; }
.button:hover { background-position: bottom left; }
.red { background: red; color: white; font-size: 12px; padding: 3px; }
Esta no es realmente una aplicación basada en contenido, por lo que no tenemos mucho formato de texto. Sin embargo, tenemos encabezados de página, enlaces y botones, por lo que los configuraremos aquí.
Encabezamiento
/*
HEADER
*/
#header { height: 68px; position: relative; }
#header h1 { position: absolute; top: 0; left: 0; z-index: 2; text-indent: -9999px; overflow: hidden; }
#header h1 a { display: block; text-indent: -9999px; width: 200px; height: 38px; border: none; background: url(/images/logo.png) no-repeat; }
#control { width: 500px; float: right; padding: 10px 237px 0 0; text-align: right; }
Nuestro pequeño encabezado de rayas no tarda mucho. Solo un pequeño reemplazo de imagen CSS para el logotipo y la ubicación de nuestros botones de control.
Liza
/*
LISTS
*/
#list { list-style: none; }
#list li { position: relative; margin: 0 0 8px 0; padding: 0 0 0 70px; width: 607px; }
#list li span { padding: 8px; -moz-border-radius: 5px; -webkit-border-radius: 5px; width: 589px; display: block; position: relative; }
.colorBlue span { background: rgb(115, 184, 191); }
.colorYellow span { background: rgb(255, 255, 255); }
.colorRed span { background: rgb(187, 49, 47); color: white; }
.colorGreen span { background: rgb(145, 191, 75); }
.tab { background: url(images/minibuttons.png) no-repeat; height: 21px; top: 4px; }
.draggertab { position: absolute; left: 0px; width: 31px; cursor: move; }
.draggertab:hover { background-position: 0 -21px; }
.colortab { position: absolute; left: 34px; width: 34px; background-position: -31px 0; cursor: pointer; }
.colortab:hover { background-position: -31px -21px; }
.deletetab { position: absolute; right: -35px; width: 15px; background-position: -82px 0; cursor: pointer; }
.deletetab:hover { background-position: -82px -21px; }
.donetab { position: absolute; right: -17px; width: 16px; background-position: -65px 0; cursor: pointer; }
.donetab:hover { background-position: -65px -21px; }
.crossout { position: absolute; top: 50%; left: 0; height: 1px; }
#share-area { margin: 20px 0 0 69px; width: 600px; }
Se necesitan muchas más cosas aquí. Aquí configuraremos el aspecto de las listas: los colores, el espaciado, las esquinas redondeadas, etc. También colocaremos todos los pequeños controles auxiliares y les daremos los fondos apropiados. Observe que solo se usa una imagen, minibuttons.png. ¡Un solo Sprite CSS para una eficiencia increíble!
Formularios
/*
FORM STUFF
*/
label { background: #999; color: white; padding: 3px; }
input[type="text"], input[type="password"] { width: 324px; border: 3px solid #999; font-size: 18px; padding: 7px; display: block; }
#add-new input[type="text"] { width: 532px; float: left; margin: 0 10px 0 69px; }
#add-new input[type="text"]:focus { border-color: #73B8BF; }
#add-new input[type="submit"] { padding: 10px 12px; }
ul#list li span input[style] { width: 90% !important; }
Los formularios en todo nuestro sitio serán los mismos, así que lo configuramos aquí. La única excepción es el área “Agregar nuevo” en nuestras listas, que es básicamente igual que cualquier otra entrada, excepto que es más grande y está flotando hacia la izquierda para acomodar el botón “Agregar”. Dado que planeamos usar hacer clic para editar, los elementos de la lista se convierten temporalmente en entradas de texto al hacer eso, por lo que planificaremos eso acortando su longitud para acomodar un botón “Guardar”.
Mensajería
/*
MESSAGING
*/
.message { padding: 10px; margin: 0 0 10px 0; width: 607px; }
.good { background: #9ff5b6; }
.bad { color: #ef0040; }
No hemos hablado demasiado sobre mensajes de error, pero podemos suponer que, debido a que se trata de una aplicación web, habrá algunos de ellos (por ejemplo, ingresó una contraseña incorrecta, sus contraseñas no coinciden, ha hecho algo, etc.). Configuraremos una clase para mensajes en general y luego clases para versiones buenas y malas.
Barra lateral
/*
SIDEBAR
*/
#ribbon { position: absolute; right: 0; width: 125px; padding: 60px 30px 0 47px; height: 756px; top: -6px; background: url(/images/ribbon-bg.png) no-repeat; }
#ribbon ul { list-style: none; }
#ribbon ul li { background: rgba(0,0,0,0.8); color: white; padding: 5px; margin: 0 0 5px 0; font-size: 12px; }
Solo algunas cosas simples para nuestra lista de recordatorios.
Moviéndose a lo largo
Nuestro desarrollador ahora tiene mucho con qué trabajar para que esta aplicación sea funcional. A continuación, abordaremos la interacción de la cuenta del usuario.
Autores de la serie
Jason Lengstorf es un desarrollador de software con sede en Missoula, MT. Es el autor de PHP para principiantes absolutos y regularmente escribe blogs sobre programación. Cuando no está pegado a su teclado, es probable que esté haciendo cola para tomar un café, preparando su propia cerveza o soñando despierto con ser un cazador de mitos.
Chris Coyier es un diseñador que actualmente vive en Chicago, IL. Es coautor de Digging Into WordPress, además de bloguero y orador sobre todo lo relacionado con el diseño. Lejos de la computadora, es probable que lo encuentren gritando a los entrenadores de fútbol en la televisión o tocando un banjo.