Задача. Добавить к текстовому полю функционал очистки значения. Если инпут не заполнен, то инпут отображается как обычно. Если заполнен, то добавляем к нему крестик, клик по которому приводит к очистке поля. Получиться должно что-то типа такого.

текстовое поле на котором есть кнопка очистки значения

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

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

Итак, html разметка (функционал будет добавляться инпутам с классом zbz-input-clearable):

<input type="text" value="тест" class="zbz-input-clearable" />

Добавляем крестик

.zbz-input-clearable {
	/* ставим инпуту фоновую картинку, но отображаем ее за пределами инпута - 150% в background-position */
	background-image: url("input-clearable-x.png");
	background-position: 150% 50%;
	background-repeat: no-repeat;
	transition: background 0.4s;
	/* добавляем справа небольшой padding, чтоб текст не залазил поверх крестика */
	padding-right: 27px;
}
.zbz-input-clearable--x {
	/* когда нужно отобразить крестик, перемещаем в правый конец инпута */
	background-position: 100% 50%;
}
.zbz-input-clearable--x-over {
	/* и подготовим стиль для ховера по крестику */
	background-image: url("input-clearable-x-hover.png");
	cursor: pointer;
}
.zbz-input-clearable::-ms-clear {
	/* убираем родной крестик очистки в IE */
	display: none;
}

И потом немного скриптовой магии

(function ($) {
	var input_class = "zbz-input-clearable",
		input_class_x = input_class + "--x",
		input_class_x_over = input_class + "--x-over",
		input_selector = "." + input_class,
		input_selector_x = "." + input_class_x,
		input_selector_x_over = "." + input_class_x_over,
		event_main = input_class + "-init",
		event_names = [event_main, "focus drop paste keydown keypress input change"].join(" "),
		btn_width = 13,
		btn_height = 13,
		btn_margin = 7;

	function tog(v) {
		return v ? "addClass" : "removeClass";
	}

	$(document).on(event_names, input_selector, function () {
		$(this)[tog(this.value)](input_class_x);
	});

	$(document).on("mousemove", input_selector_x, function (e) {
		var input = $(this),
			input_width = this.offsetWidth,
			input_height = this.offsetHeight,
			input_border_bottom = parseFloat(input.css("borderBottomWidth")),
			input_border_right = parseFloat(input.css("borderRightWidth")),
			input_border_left = parseFloat(input.css("borderLeftWidth")),
			input_border_top = parseFloat(input.css("borderTopWidth")),
			input_border_hr = input_border_left + input_border_right,
			input_border_vr = input_border_top + input_border_bottom,
			client_rect = this.getBoundingClientRect(),
			input_cursor_pos_x = e.clientX - client_rect.left,
			input_cursor_pos_y = e.clientY - client_rect.top,
			is_over_cross = true;

		is_over_cross =
			is_over_cross && input_cursor_pos_x >= input_width - input_border_hr - btn_margin - btn_width;
		is_over_cross =
			is_over_cross && input_cursor_pos_x <= input_width - input_border_hr - btn_margin;
		is_over_cross =
			is_over_cross && input_cursor_pos_y >= (input_height - input_border_vr - btn_height) / 2;
		is_over_cross =
			is_over_cross &&
			input_cursor_pos_y <= (input_height - input_border_vr - btn_height) / 2 + btn_height;

		$(this)[tog(is_over_cross)](input_class_x_over);
	});

	$(document).on("click", input_selector_x_over, function () {
		$(this).removeClass([input_class_x, input_class_x_over].join(" ")).val("").trigger("input");
	});

	$(function () {
		$(input_selector).trigger(event_main);
	});
})(jQuery);

Пример