{"id":14,"date":"2026-09-16T10:28:30","date_gmt":"2026-09-16T10:28:30","guid":{"rendered":"https:\/\/docs.latw.ai\/uncategorized\/css-class-map\/"},"modified":"2026-09-16T10:28:30","modified_gmt":"2026-09-16T10:28:30","slug":"css-class-map","status":"publish","type":"post","link":"https:\/\/docs.latw.ai\/pl\/esti-to-wordpress\/css-class-map\/","title":{"rendered":"CSS Class Map"},"content":{"rendered":"<h1>CSS class map<\/h1>\n<p>Every class the plugin renders is prefixed <code>osfec-<\/code> and follows BEM: <code>block__element--modifier<\/code>. The outermost element<br \/>\nof every component also carries the bare <code>.osfec<\/code> class, which is where<br \/>\nthe <a href=\"\/esti-to-wordpress\/styling#custom-properties\">custom properties<\/a> are declared \u2014 so <code>.osfec .osfec-card<\/code> is always a valid,<br \/>\nhigher-specificity selector.<\/p>\n<h2>Wrappers<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec<\/code><\/td>\n<td>On every component the plugin renders. Sets the properties and the max width<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-archive<\/code><\/td>\n<td>The offer archive page<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer<\/code><\/td>\n<td>The single offer article (alongside WordPress&#8217;s own <code>post_class()<\/code> output)<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offers<\/code><\/td>\n<td>The shortcode and block wrapper. <code>.osfec.osfec-offers<\/code> drops the side padding<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-main<\/code><\/td>\n<td>Only on block themes: the <code>&lt;main&gt;<\/code> the plugin opens around its pages<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Shared pieces<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec-kicker<\/code>, <code>.osfec-kicker__sep<\/code><\/td>\n<td>Small uppercase label above a heading<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-section<\/code>, <code>.osfec-section__head<\/code><\/td>\n<td>A titled section on the offer page<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-panel<\/code>, <code>.osfec-panel__body<\/code><\/td>\n<td>The bordered card that wraps a block of content<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-button<\/code>, <code>.osfec-button--ghost<\/code><\/td>\n<td>Primary and secondary button. Styled as <code>.osfec .osfec-button<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-empty<\/code><\/td>\n<td>&#8220;No offers match your criteria.&#8221;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Listing<\/h2>\n<pre><code class=\"language-html\">\n&lt;ul class=\"osfec-list\"&gt;                        &lt;!-- + .osfec-list--grid for a grid --&gt;\n    &lt;li class=\"osfec-card-item\"&gt;\n        &lt;a class=\"osfec-card__link\"&gt;\n            &lt;article class=\"osfec-card\"&gt;\n                &lt;div class=\"osfec-card__media\"&gt;&lt;img&gt;&lt;\/div&gt;\n                &lt;div class=\"osfec-card__content\"&gt;\n                    &lt;div class=\"osfec-card__topline\"&gt;\n                        &lt;span class=\"osfec-card__type\"&gt;Apartment for sale&lt;\/span&gt;\n                        &lt;span class=\"osfec-card__location\"&gt;Bia\u0142ystok&lt;\/span&gt;\n                    &lt;\/div&gt;\n                    &lt;h2 class=\"osfec-card__title\"&gt;\u2026&lt;\/h2&gt;\n                    &lt;ul class=\"osfec-card__details\"&gt;\n                        &lt;li class=\"osfec-card__detail\"&gt;64 m\u00b2&lt;\/li&gt;\n                    &lt;\/ul&gt;\n                    &lt;div class=\"osfec-card__footer\"&gt;\n                        &lt;div class=\"osfec-card__price-wrap\"&gt;\n                            &lt;span class=\"osfec-card__price-label\"&gt;Price&lt;\/span&gt;\n                            &lt;span class=\"osfec-card__price\"&gt;540 000 PLN&lt;\/span&gt;\n                        &lt;\/div&gt;\n                        &lt;span class=\"osfec-card__cta\"&gt;View offer\n              &lt;span class=\"osfec-card__cta-arrow\"&gt;\u2192&lt;\/span&gt;\n            &lt;\/span&gt;\n                    &lt;\/div&gt;\n                &lt;\/div&gt;\n            &lt;\/article&gt;\n        &lt;\/a&gt;\n    &lt;\/li&gt;\n&lt;\/ul&gt;<\/code><\/pre>\n<p>Notes:<\/p>\n<ul>\n<li><code>.osfec-list--grid<\/code> is added by the <code>columns<\/code> attribute and reads <code>--osfec-columns<\/code> for the column count. It collapses<br \/>\nto two columns at 980px and one at 600px.<\/li>\n<li><code>.osfec-card__price--muted<\/code> replaces the price when the price is hidden (&#8220;Price on request&#8221;).<\/li>\n<li>Hover and focus states are driven from <code>.osfec-card__link<\/code>, so <code>.osfec-card__link:hover .osfec-card { \u2026 }<\/code> is the<br \/>\nright shape for a custom hover.<\/li>\n<li><code>.osfec-offers__more<\/code> is the paragraph holding the link to the archive, printed by <code>more<\/code>.<\/li>\n<\/ul>\n<h2>Filter bar and toolbar<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec-filters<\/code><\/td>\n<td>The <code>&lt;form&gt;<\/code>, submitting with GET<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__grid<\/code><\/td>\n<td>The field grid<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__field<\/code><\/td>\n<td>One field<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__field--pair<\/code><\/td>\n<td>A From\/To pair (price, area)<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__label<\/code><\/td>\n<td>Field label<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__input<\/code><\/td>\n<td>Every input and select in the bar<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__actions<\/code><\/td>\n<td>Row holding the submit button and the reset link<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-filters__reset<\/code><\/td>\n<td>&#8220;Clear filters&#8221;<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-toolbar<\/code><\/td>\n<td>The sorting and result-count row on the archive<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-toolbar__sort<\/code>, <code>.osfec-toolbar__label<\/code><\/td>\n<td>The sorting form and its label<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-toolbar__count<\/code><\/td>\n<td>&#8220;Offers found: 128&#8221;<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-pagination<\/code><\/td>\n<td>Archive pagination; the links inside are WordPress&#8217;s own <code>.page-numbers<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Single offer<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec-breadcrumb<\/code><\/td>\n<td>Home \/ Offers \/ this offer<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__head<\/code>, <code>.osfec-offer__headline<\/code><\/td>\n<td>Header block with the kicker, title and location<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__title<\/code><\/td>\n<td>The <code>&lt;h1&gt;<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__location<\/code><\/td>\n<td>Location line, with an inline SVG pin<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__headline-price<\/code><\/td>\n<td>The price block in the header; reuses <code>.osfec-card__price-label<\/code> and <code>.osfec-card__price<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__price-previous<\/code><\/td>\n<td>Struck-through previous price, only when it was higher<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-facts<\/code>, <code>.osfec-fact<\/code>, <code>.osfec-fact__label<\/code>, <code>.osfec-fact__value<\/code><\/td>\n<td>The four headline figures<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-attributes<\/code>, <code>.osfec-attributes__item<\/code>, <code>.osfec-attributes__label<\/code>, <code>.osfec-attributes__value<\/code><\/td>\n<td>The bordered attribute grid<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__id<\/code><\/td>\n<td>&#8220;Offer ID: 12345&#8221;<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__body<\/code>, <code>.osfec-offer__main<\/code>, <code>.osfec-offer__sidebar<\/code><\/td>\n<td>Two-column layout below the facts<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__subtitle<\/code><\/td>\n<td>Section heading inside a panel<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-description<\/code><\/td>\n<td>The imported description, capped at the reading width<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-tags<\/code>, <code>.osfec-tags__item<\/code><\/td>\n<td>Marketing labels from Esti<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-offer__back<\/code><\/td>\n<td>&#8220;Back to all offers&#8221;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Gallery<\/h2>\n<pre><code class=\"language-html\">\n&lt;div class=\"osfec-slider\" data-osfec-slider tabindex=\"0\"&gt;\n    &lt;div class=\"osfec-slider__track\" data-osfec-track&gt;\n        &lt;figure class=\"osfec-slider__slide\"&gt;&lt;img&gt;&lt;\/figure&gt;\n    &lt;\/div&gt;\n    &lt;button class=\"osfec-slider__nav osfec-slider__nav--prev\" data-osfec-prev&gt;\u2026&lt;\/button&gt;\n    &lt;button class=\"osfec-slider__nav osfec-slider__nav--next\" data-osfec-next&gt;\u2026&lt;\/button&gt;\n    &lt;p class=\"osfec-slider__counter\"&gt;&lt;span data-osfec-current&gt;1&lt;\/span&gt; \/ 12&lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<ul>\n<li>The <code>data-osfec-*<\/code> attributes are the script&#8217;s hooks. <strong>Rename a class freely; do not remove those attributes<\/strong> unless<br \/>\nyou are also replacing <code>assets\/js\/gallery.js<\/code>.<\/li>\n<li><code>.osfec-slider__track--dragging<\/code> is added while a pointer drag is in progress \u2014 useful for suppressing transitions.<\/li>\n<li>The track is moved with a transform rather than by scrolling, deliberately: a horizontal scroll container swallows the<br \/>\nvertical wheel and the page would stop scrolling under the pointer.<\/li>\n<li>The navigation buttons and the counter are only rendered when the offer has more than one photo.<\/li>\n<\/ul>\n<h2>Media tiles<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec-media<\/code><\/td>\n<td>Wrapper for the video and virtual tour tiles<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-media__grid<\/code><\/td>\n<td>The tile grid<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-media__card<\/code><\/td>\n<td>One tile, an external link opening in a new tab<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-media__icon<\/code>, <code>.osfec-media__label<\/code><\/td>\n<td>The icon and label on a tile<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The whole block is omitted when the offer has neither a video nor a tour.<\/p>\n<h2>Agent card<\/h2>\n<table>\n<thead>\n<tr>\n<th>Class<\/th>\n<th>Where<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>.osfec-agent<\/code><\/td>\n<td>The card<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-agent--no-photo<\/code><\/td>\n<td>Added when the directory has no portrait<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-agent__portrait<\/code><\/td>\n<td>Photo wrapper<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-agent__info<\/code>, <code>.osfec-agent__name<\/code>, <code>.osfec-agent__position<\/code><\/td>\n<td>Name, office and role<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-agent__actions<\/code>, <code>.osfec-agent__action<\/code>, <code>.osfec-agent__action-text<\/code><\/td>\n<td><code>tel:<\/code> and <code>mailto:<\/code> links<\/td>\n<\/tr>\n<tr>\n<td><code>.osfec-agent__icon<\/code><\/td>\n<td>Inline SVG icon inside an action<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The card is skipped entirely when the offer carries no agent name.<\/p>\n<h2>Admin<\/h2>\n<p>The sync log screen prints a handful of classes of its own, styled inline: <code>.osfec-status<\/code> with the modifiers<br \/>\n<code>--running<\/code>, <code>--success<\/code>, <code>--warning<\/code>, <code>--failed<\/code>, <code>--interrupted<\/code>, plus <code>.osfec-result<\/code>, <code>.osfec-message<\/code> and<br \/>\n<code>.osfec-event--error<\/code> \/ <code>.osfec-event--warning<\/code> on event rows.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CSS class map Every class the plugin renders is prefixed osfec- and follows BEM: block__element&#8211;modifier. The outermost element of every component also carries the bare .osfec\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_latwm_translated_slug":"","footnotes":""},"categories":[2],"tags":[],"class_list":["post-14","post","type-post","status-publish","format-standard","hentry","category-esti-to-wordpress"],"_links":{"self":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/14","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/comments?post=14"}],"version-history":[{"count":1,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/14\/revisions"}],"predecessor-version":[{"id":50,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/14\/revisions\/50"}],"wp:attachment":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/media?parent=14"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/categories?post=14"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/tags?post=14"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}