diff --git a/src/components/deck-card-editor.vue b/src/components/deck-card-editor.vue
index e161209..96f6349 100644
--- a/src/components/deck-card-editor.vue
+++ b/src/components/deck-card-editor.vue
@@ -29,11 +29,8 @@
 import { Component, Prop, Vue } from 'vue-property-decorator'
 import DeckCardEditorMenu from '@/components/deck-card-editor-menu.vue'
 import {
-  elementNameToMenuState,
   menuActionToCommand,
-  getElementAndParentName,
-  marks,
-  blocks,
+  getActiveMarksAndBlocks,
   State,
   movementKeys,
   controlSequenceKeys
@@ -48,45 +45,33 @@ export default class DeckCardEditor extends Vue {
 
   private contentInFocus = false
 
-  private menuState: State = {
-    bold: false,
-    italic: false,
-    paragraph: true,
-    heading1: false,
-    heading2: false,
-    heading3: false,
-    bulletList: false,
-    spacer: false,
-    separator: false,
-    statBlock: false
+  private defaultMenuState (): State {
+    return {
+      bold: false,
+      italic: false,
+      paragraph: true,
+      heading1: false,
+      heading2: false,
+      heading3: false,
+      bulletList: false,
+      spacer: false,
+      separator: false,
+      statBlock: false
+    }
   }
 
-  private clearMarks () {
-    marks.forEach(mark => {
-      this.menuState[mark] = false
-    })
+  private menuState = this.defaultMenuState()
+
+  private resetMenuState () {
+    this.menuState = this.defaultMenuState()
   }
 
-  private toggleBlock (name: string) {
-    blocks.forEach(block => {
-      this.menuState[block] = false
-    })
-    this.menuState[name] = true
-  }
-
-  private setMenuState (elementName: string, parentName?: string) {
-    const stateName = elementNameToMenuState[elementName]
-
-    // marks are always inside a block element
-    if (marks.indexOf(stateName) >= 0 && parentName) {
-      const parentStateName = elementNameToMenuState[parentName]
-      // marks are inclusive like checkboxes
-      this.menuState[stateName] = true
-      // but blocks are exclusive like radio buttons
-      this.toggleBlock(parentStateName)
-    } else {
-      this.clearMarks()
-      this.toggleBlock(stateName)
+  private setMenuState (marks: string[], block: string) {
+    this.resetMenuState()
+    marks.forEach(mark => { this.menuState[mark] = true })
+    if (block !== 'paragraph') {
+      this.menuState.paragraph = false
+      this.menuState[block] = true
     }
   }
 
@@ -105,11 +90,8 @@ export default class DeckCardEditor extends Vue {
     const sel = window.getSelection()?.focusNode
     if (!sel) return
 
-    const [elementName, parentName] = getElementAndParentName(sel)
-    console.log('focussed element', elementName, parentName)
-    if (!elementName) return
-
-    this.setMenuState(elementName, parentName)
+    const { marks, block } = getActiveMarksAndBlocks(sel as HTMLElement)
+    this.setMenuState(marks, block)
   }
 
   private syncMenuStateIfFocussed () {
diff --git a/src/editor/index.ts b/src/editor/index.ts
index 97ea19e..8f23a94 100644
--- a/src/editor/index.ts
+++ b/src/editor/index.ts
@@ -1,8 +1,9 @@
+import { elementNameToMenuState, marks, blocks } from './constants'
+
 export type State = KV<boolean>
 export {
   movementKeys,
   controlSequenceKeys,
-  elementNameToMenuState,
   marks,
   blocks
 } from './constants'
@@ -33,10 +34,41 @@ export const menuActionToCommand: KV<() => boolean> = {
   italic: simpleAction('italic')
 }
 
-export function getElementAndParentName (el: Node) {
-  const element = el.nodeName === '#text' ? el.parentElement : el
-  return [
-    element?.nodeName,
-    element?.parentElement?.nodeName
-  ]
+export function getActiveMarksAndBlocks (el: HTMLElement): {
+  marks: string[];
+  block: string;
+} {
+  let activeBlock = 'paragraph'
+  const activeMarks: string[] = []
+
+  const focussedEl = el.nodeName === '#text' ? el.parentElement : el
+  if (!focussedEl) return { marks: activeMarks, block: activeBlock }
+
+  const focussedState = elementNameToMenuState[focussedEl.nodeName]
+  if (!focussedState) return { marks: activeMarks, block: activeBlock }
+
+  if (blocks.indexOf(focussedState) >= 0) {
+    activeBlock = focussedState
+    return { marks: activeMarks, block: activeBlock }
+  }
+
+  let wrappingEl = focussedEl.parentElement
+  let wrappingState: string
+
+  if (marks.indexOf(focussedState) >= 0) {
+    activeMarks.push(focussedState)
+
+    while (wrappingEl) {
+      wrappingState = elementNameToMenuState[wrappingEl.nodeName]
+      if (marks.indexOf(wrappingState) < 0) {
+        if (blocks.indexOf(wrappingState) >= 0) activeBlock = wrappingState
+        break
+      }
+
+      activeMarks.push(wrappingState)
+      wrappingEl = wrappingEl.parentElement
+    }
+  }
+
+  return { marks: activeMarks, block: activeBlock }
 }