diff --git a/examples/basic_sprite.rs b/examples/basic_sprite.rs
index bfdbefb28115ce1a89a059afc05b7ba2c01c572a..09073d0dd2ed969a571185079afa9414ad7c1b80 100644
--- a/examples/basic_sprite.rs
+++ b/examples/basic_sprite.rs
@@ -27,7 +27,6 @@ fn setup(
             "馃榾馃榾馃榾 x => y",
             attrs,
         ),
-        text_position: CosmicTextPosition::Center,
         sprite_bundle: SpriteBundle {
             sprite: Sprite {
                 custom_size: Some(Vec2::new(primary_window.width(), primary_window.height())),
diff --git a/examples/basic_ui.rs b/examples/basic_ui.rs
index 2584d4c57c19414a58f3c2e64d08bf754d66acbe..94eb841d7697f97b9589aa2f45bd7359f863794f 100644
--- a/examples/basic_ui.rs
+++ b/examples/basic_ui.rs
@@ -23,7 +23,6 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
                 vec![("Banana", attrs)],
                 attrs,
             ),
-            text_position: CosmicTextPosition::Center,
             ..default()
         },))
         .id();
diff --git a/examples/font_per_widget.rs b/examples/font_per_widget.rs
index f6f6959d825d7800134a9b529e9f8b8ba8ce5bc9..17282745303a8cd5cc5de4f2249dae72f73ab705 100644
--- a/examples/font_per_widget.rs
+++ b/examples/font_per_widget.rs
@@ -101,7 +101,6 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
                 lines,
                 attrs,
             ),
-            text_position: bevy_cosmic_edit::CosmicTextPosition::Center,
             ..default()
         })
         .id();
@@ -117,7 +116,6 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
                 "Widget 2.\nClick on me =>",
                 attrs_2,
             ),
-            text_position: CosmicTextPosition::Center,
             ..default()
         })
         .id();
diff --git a/examples/multiple_sprites.rs b/examples/multiple_sprites.rs
index 13d15f419143813b983dc5ec700b9e95ca2dc179..e8623fcaf16552907c23699ac2a987aa010fd2c3 100644
--- a/examples/multiple_sprites.rs
+++ b/examples/multiple_sprites.rs
@@ -22,7 +22,6 @@ fn setup(
     attrs = attrs.color(bevy_color_to_cosmic(Color::PURPLE));
 
     commands.spawn(CosmicEditBundle {
-        text_position: CosmicTextPosition::Center,
         fill_color: FillColor(Color::ALICE_BLUE),
         buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text(
             &mut font_system,
@@ -44,7 +43,6 @@ fn setup(
     });
 
     commands.spawn(CosmicEditBundle {
-        text_position: CosmicTextPosition::Center,
         fill_color: FillColor(Color::GRAY.with_a(0.5)),
         buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text(
             &mut font_system,
diff --git a/examples/placeholder.rs b/examples/placeholder.rs
index bc081eac7c505b91ecf1b0d5160ab98d14ef3124..82d459515548428c7a89a781ad60f275a872f56b 100644
--- a/examples/placeholder.rs
+++ b/examples/placeholder.rs
@@ -24,7 +24,6 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
                 CosmicEditBundle {
                     buffer: CosmicBuffer::new(&mut font_system, Metrics::new(20., 20.))
                         .with_rich_text(&mut font_system, vec![("", attrs)], attrs),
-                    text_position: CosmicTextPosition::Center,
                     ..default()
                 },
                 Placeholder::new(
diff --git a/examples/readonly.rs b/examples/readonly.rs
index b41ad9f393a78a68bc971b1911bca9f1c7a1eb52..0a76bd89f69ca32326a3256605b251a42ac6d92f 100644
--- a/examples/readonly.rs
+++ b/examples/readonly.rs
@@ -23,7 +23,6 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
     // spawn editor
     let cosmic_edit = commands
         .spawn(CosmicEditBundle {
-            text_position: CosmicTextPosition::Center,
             buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text(
                 &mut font_system,
                 "馃榾馃榾馃榾 x => y\nRead only widget",
diff --git a/examples/sprite_and_ui_clickable.rs b/examples/sprite_and_ui_clickable.rs
index 31d4e76ce8f5f033d2ca9879082fc40ab209681a..0afb584c4e46d19013cf82c0fe977aeea85d1ed4 100644
--- a/examples/sprite_and_ui_clickable.rs
+++ b/examples/sprite_and_ui_clickable.rs
@@ -15,6 +15,8 @@ fn setup(mut commands: Commands) {
                 Attrs::new().color(bevy_color_to_cosmic(Color::GREEN)),
             )),
             max_lines: CosmicMaxLines(1),
+            mode: CosmicMode::InfiniteLine,
+            text_position: CosmicTextPosition::Left { padding: 5 },
             ..default()
         })
         .id();
@@ -35,6 +37,8 @@ fn setup(mut commands: Commands) {
 
     // Sprite editor
     commands.spawn((CosmicEditBundle {
+        max_lines: CosmicMaxLines(1),
+        mode: CosmicMode::InfiniteLine,
         sprite_bundle: SpriteBundle {
             // Sets size of text box
             sprite: Sprite {
diff --git a/src/input.rs b/src/input.rs
index 087cef09eeb029f61878ad86930eb2c2a5511f41..9bb5477d732c52e0822f1c48d120e36e0a5019b1 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -123,7 +123,7 @@ pub(crate) fn input_mouse(
         }
 
         let (padding_x, padding_y) = match text_position {
-            CosmicTextPosition::Center => (
+            CosmicTextPosition::Center { padding: _ } => (
                 get_x_offset_center(width * scale_factor, &buffer),
                 get_y_offset_center(height * scale_factor, &buffer),
             ),
@@ -153,7 +153,7 @@ pub(crate) fn input_mouse(
                 camera_transform,
             ) {
                 let (mut x, y) = point(node_cursor_pos);
-                x += x_offset.0.unwrap_or((0., 0.)).0 as i32;
+                x += x_offset.left as i32;
                 if shift {
                     editor.action(&mut font_system.0, Action::Drag { x, y });
                 } else {
@@ -193,7 +193,7 @@ pub(crate) fn input_mouse(
                 camera_transform,
             ) {
                 let (mut x, y) = point(node_cursor_pos);
-                x += x_offset.0.unwrap_or((0., 0.)).0 as i32;
+                x += x_offset.left as i32;
                 if active_editor.is_changed() && !shift {
                     editor.action(&mut font_system.0, Action::Click { x, y });
                 } else {
@@ -355,13 +355,28 @@ pub(crate) fn input_kb(
         if keys.just_pressed(KeyCode::Backspace) & !readonly {
             // fix for issue #8
             let select = editor.selection();
-            if select != Selection::None {
-                // TODO: fix zero-width selections if needed
-                //
-                // if editor.cursor().line == select.line && editor.cursor().index == select.index {
-                //     editor.set_selection(Selection::None);
-                // }
+            match select {
+                Selection::Line(cursor) => {
+                    if editor.cursor().line == cursor.line && editor.cursor().index == cursor.index
+                    {
+                        editor.set_selection(Selection::None);
+                    }
+                }
+                Selection::Normal(cursor) => {
+                    if editor.cursor().line == cursor.line && editor.cursor().index == cursor.index
+                    {
+                        editor.set_selection(Selection::None);
+                    }
+                }
+                Selection::Word(cursor) => {
+                    if editor.cursor().line == cursor.line && editor.cursor().index == cursor.index
+                    {
+                        editor.set_selection(Selection::None);
+                    }
+                }
+                Selection::None => {}
             }
+
             *is_deleting = true;
             #[cfg(target_arch = "wasm32")]
             editor.action(&mut font_system.0, Action::Backspace);
@@ -372,6 +387,7 @@ pub(crate) fn input_kb(
         }
         if keys.just_pressed(KeyCode::Delete) && !readonly {
             editor.action(&mut font_system.0, Action::Delete);
+            editor.with_buffer_mut(|b| b.set_redraw(true));
         }
         if keys.just_pressed(KeyCode::Escape) {
             editor.action(&mut font_system.0, Action::Escape);
diff --git a/src/layout.rs b/src/layout.rs
index 2665d9ae1b0dcc12c28c6a6beb83b1bdd35960eb..f5d0bce834a9809cf2fbd15f35922136e5655fd3 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -4,10 +4,10 @@ use cosmic_text::Affinity;
 
 use self::buffer::{get_x_offset_center, get_y_offset_center};
 
-#[derive(Component, Default)]
+#[derive(Component, Default, Deref, DerefMut, Debug)]
 pub struct CosmicPadding(pub Vec2);
 
-#[derive(Component, Default)]
+#[derive(Component, Default, Deref, DerefMut)]
 pub struct CosmicWidgetSize(pub Vec2);
 
 pub fn reshape(mut query: Query<&mut CosmicEditor>, mut font_system: ResMut<CosmicFontSystem>) {
@@ -46,7 +46,7 @@ pub fn set_padding(
         }
 
         padding.0 = match position {
-            CosmicTextPosition::Center => Vec2::new(
+            CosmicTextPosition::Center { padding: _ } => Vec2::new(
                 get_x_offset_center(size.0.x, &buffer) as f32,
                 get_y_offset_center(size.0.y, &buffer) as f32,
             ),
@@ -91,7 +91,7 @@ pub fn set_buffer_size(
 ) {
     for (mut buffer, mode, size, position) in query.iter_mut() {
         let padding_x = match position {
-            CosmicTextPosition::Center => 0.,
+            CosmicTextPosition::Center { padding: _ } => 0.,
             CosmicTextPosition::TopLeft { padding } => *padding as f32,
             CosmicTextPosition::Left { padding } => *padding as f32,
         };
@@ -114,47 +114,58 @@ pub fn new_image_from_default(
     }
 }
 
-pub fn set_cursor(
+pub fn set_x_offset(
     mut query: Query<(
         &mut XOffset,
         &CosmicMode,
         &CosmicEditor,
-        &CosmicBuffer,
         &CosmicWidgetSize,
-        &CosmicPadding,
+        &CosmicTextPosition,
     )>,
 ) {
-    for (mut x_offset, mode, editor, buffer, size, padding) in query.iter_mut() {
+    for (mut x_offset, mode, editor, size, position) in query.iter_mut() {
+        if mode != &CosmicMode::InfiniteLine {
+            return;
+        }
+
         let mut cursor_x = 0.;
-        if mode == &CosmicMode::InfiniteLine {
-            if let Some(line) = buffer.layout_runs().next() {
-                for (idx, glyph) in line.glyphs.iter().enumerate() {
-                    if editor.cursor().affinity == Affinity::Before {
-                        if idx <= editor.cursor().index {
-                            cursor_x += glyph.w;
-                        }
-                    } else if idx < editor.cursor().index {
+        let cursor = editor.cursor();
+
+        if let Some(line) = editor.with_buffer(|b| b.clone()).layout_runs().next() {
+            for (idx, glyph) in line.glyphs.iter().enumerate() {
+                if cursor.affinity == Affinity::Before {
+                    if idx <= cursor.index {
                         cursor_x += glyph.w;
                     } else {
                         break;
                     }
+                } else if idx < cursor.index {
+                    cursor_x += glyph.w;
+                } else {
+                    break;
                 }
             }
         }
 
-        if mode == &CosmicMode::InfiniteLine && x_offset.0.is_none() {
-            *x_offset = XOffset(Some((0., size.0.x - 2. * padding.0.x)));
+        let padding_x = match position {
+            CosmicTextPosition::Center { padding } => *padding as f32,
+            CosmicTextPosition::TopLeft { padding } => *padding as f32,
+            CosmicTextPosition::Left { padding } => *padding as f32,
+        };
+
+        if x_offset.width == 0. {
+            x_offset.width = size.x - padding_x * 2.;
         }
 
-        if let Some((x_min, x_max)) = x_offset.0 {
-            if cursor_x > x_max {
-                let diff = cursor_x - x_max;
-                *x_offset = XOffset(Some((x_min + diff, cursor_x)));
-            }
-            if cursor_x < x_min {
-                let diff = x_min - cursor_x;
-                *x_offset = XOffset(Some((cursor_x, x_max - diff)));
-            }
+        let right = x_offset.width + x_offset.left;
+
+        if cursor_x > right {
+            let diff = cursor_x - right;
+            x_offset.left += diff;
+        }
+        if cursor_x < x_offset.left {
+            let diff = x_offset.left - cursor_x;
+            x_offset.left -= diff;
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index be981847c2a7b0dcef04a622b9901e489eff6597..726f5a242712ffeace3c930240f7ae0691c553c0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -30,8 +30,8 @@ use input::{input_kb, input_mouse, ClickTimer};
 #[cfg(target_arch = "wasm32")]
 use input::{poll_wasm_paste, WasmPaste, WasmPasteAsyncChannel};
 use layout::{
-    new_image_from_default, reshape, set_buffer_size, set_cursor, set_padding,
-    set_sprite_size_from_ui, set_widget_size, CosmicPadding, CosmicWidgetSize,
+    new_image_from_default, reshape, set_buffer_size, set_padding, set_sprite_size_from_ui,
+    set_widget_size, set_x_offset, CosmicPadding, CosmicWidgetSize,
 };
 use render::{blink_cursor, render_texture, SwashCacheState};
 
@@ -55,16 +55,17 @@ pub enum CursorConfig {
 }
 
 /// Enum representing the position of the cosmic text.
-#[derive(Clone, Component, Default)]
+#[derive(Clone, Component)]
 pub enum CosmicTextPosition {
-    #[default]
-    Center,
-    TopLeft {
-        padding: i32,
-    },
-    Left {
-        padding: i32,
-    },
+    Center { padding: i32 },
+    TopLeft { padding: i32 },
+    Left { padding: i32 },
+}
+
+impl Default for CosmicTextPosition {
+    fn default() -> Self {
+        CosmicTextPosition::Center { padding: 5 }
+    }
 }
 
 #[derive(Event, Debug)]
@@ -77,7 +78,10 @@ pub struct CosmicFontSystem(pub FontSystem);
 pub struct ReadOnly; // tag component
 
 #[derive(Component, Debug, Default)]
-pub struct XOffset(Option<(f32, f32)>);
+pub struct XOffset {
+    pub left: f32,
+    pub width: f32,
+}
 
 #[derive(Component, Deref, DerefMut)]
 pub struct CosmicEditor {
@@ -170,7 +174,7 @@ impl Default for CosmicEditBundle {
                 visibility: Visibility::Hidden,
                 ..default()
             },
-            x_offset: XOffset(None),
+            x_offset: Default::default(),
             padding: Default::default(),
             widget_size: Default::default(),
         }
@@ -215,7 +219,7 @@ impl Plugin for CosmicEditPlugin {
             set_widget_size,
             set_buffer_size,
             set_padding,
-            set_cursor,
+            set_x_offset,
         )
             .chain();
 
diff --git a/src/render.rs b/src/render.rs
index 730d8c08d4680f641f6ea2d58eedd6dd8c4c53a0..78e376ed4d9c069ce0bbc773944d780dd49b0bfc 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -4,8 +4,8 @@ use image::{imageops::FilterType, GenericImageView};
 
 use crate::{
     layout::{CosmicPadding, CosmicWidgetSize},
-    CosmicBackground, CosmicBuffer, CosmicEditor, CosmicFontSystem, CursorColor, DefaultAttrs,
-    FillColor, ReadOnly, SelectionColor, XOffset,
+    CosmicBackground, CosmicBuffer, CosmicEditor, CosmicFontSystem, CosmicTextPosition,
+    CursorColor, DefaultAttrs, FillColor, ReadOnly, SelectionColor, XOffset,
 };
 
 #[derive(Resource)]
@@ -77,6 +77,7 @@ pub(crate) fn render_texture(
         &CosmicPadding,
         &XOffset,
         Option<&ReadOnly>,
+        &CosmicTextPosition,
     )>,
     mut font_system: ResMut<CosmicFontSystem>,
     mut images: ResMut<Assets<Image>>,
@@ -95,6 +96,7 @@ pub(crate) fn render_texture(
         padding,
         x_offset,
         readonly_opt,
+        position,
     ) in query.iter_mut()
     {
         // Draw background
@@ -133,6 +135,12 @@ pub(crate) fn render_texture(
             .color_opt
             .unwrap_or(cosmic_text::Color::rgb(0, 0, 0));
 
+        let min_pad = match position {
+            CosmicTextPosition::Center { padding } => *padding as f32,
+            CosmicTextPosition::TopLeft { padding } => *padding as f32,
+            CosmicTextPosition::Left { padding } => *padding as f32,
+        };
+
         let draw_closure = |x, y, w, h, color| {
             for row in 0..h as i32 {
                 for col in 0..w as i32 {
@@ -140,8 +148,8 @@ pub(crate) fn render_texture(
                         &mut pixels,
                         size.0.x as i32,
                         size.0.y as i32,
-                        x + col + padding.0.x as i32 - x_offset.0.unwrap_or((0., 0.)).0 as i32,
-                        y + row + padding.0.y as i32,
+                        x + col + padding.x.max(min_pad) as i32 - x_offset.left as i32,
+                        y + row + padding.y as i32,
                         color,
                     );
                 }